diff options
Diffstat (limited to 'drivers')
110 files changed, 4081 insertions, 2266 deletions
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index bce34afadcd0..ea55e0179f81 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -39,8 +39,9 @@ acpi-y += processor_core.o | |||
39 | acpi-y += ec.o | 39 | acpi-y += ec.o |
40 | acpi-$(CONFIG_ACPI_DOCK) += dock.o | 40 | acpi-$(CONFIG_ACPI_DOCK) += dock.o |
41 | acpi-y += pci_root.o pci_link.o pci_irq.o | 41 | acpi-y += pci_root.o pci_link.o pci_irq.o |
42 | acpi-$(CONFIG_X86_INTEL_LPSS) += acpi_lpss.o | 42 | acpi-y += acpi_lpss.o |
43 | acpi-y += acpi_platform.o | 43 | acpi-y += acpi_platform.o |
44 | acpi-y += acpi_pnp.o | ||
44 | acpi-y += power.o | 45 | acpi-y += power.o |
45 | acpi-y += event.o | 46 | acpi-y += event.o |
46 | acpi-y += sysfs.o | 47 | acpi-y += sysfs.o |
@@ -63,9 +64,9 @@ obj-$(CONFIG_ACPI_FAN) += fan.o | |||
63 | obj-$(CONFIG_ACPI_VIDEO) += video.o | 64 | obj-$(CONFIG_ACPI_VIDEO) += video.o |
64 | obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o | 65 | obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o |
65 | obj-$(CONFIG_ACPI_PROCESSOR) += processor.o | 66 | obj-$(CONFIG_ACPI_PROCESSOR) += processor.o |
66 | obj-$(CONFIG_ACPI_CONTAINER) += container.o | 67 | obj-y += container.o |
67 | obj-$(CONFIG_ACPI_THERMAL) += thermal.o | 68 | obj-$(CONFIG_ACPI_THERMAL) += thermal.o |
68 | obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o | 69 | obj-y += acpi_memhotplug.o |
69 | obj-$(CONFIG_ACPI_BATTERY) += battery.o | 70 | obj-$(CONFIG_ACPI_BATTERY) += battery.o |
70 | obj-$(CONFIG_ACPI_SBS) += sbshc.o | 71 | obj-$(CONFIG_ACPI_SBS) += sbshc.o |
71 | obj-$(CONFIG_ACPI_SBS) += sbs.o | 72 | obj-$(CONFIG_ACPI_SBS) += sbs.o |
diff --git a/drivers/acpi/acpi_cmos_rtc.c b/drivers/acpi/acpi_cmos_rtc.c index 961b45d18a5d..2da8660262e5 100644 --- a/drivers/acpi/acpi_cmos_rtc.c +++ b/drivers/acpi/acpi_cmos_rtc.c | |||
@@ -68,7 +68,7 @@ static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev, | |||
68 | return -ENODEV; | 68 | return -ENODEV; |
69 | } | 69 | } |
70 | 70 | ||
71 | return 0; | 71 | return 1; |
72 | } | 72 | } |
73 | 73 | ||
74 | static void acpi_remove_cmos_rtc_space_handler(struct acpi_device *adev) | 74 | static void acpi_remove_cmos_rtc_space_handler(struct acpi_device *adev) |
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c index c4a5d87ede7e..185334114d71 100644 --- a/drivers/acpi/acpi_extlog.c +++ b/drivers/acpi/acpi_extlog.c | |||
@@ -220,13 +220,13 @@ static int __init extlog_init(void) | |||
220 | goto err; | 220 | goto err; |
221 | } | 221 | } |
222 | 222 | ||
223 | extlog_l1_hdr = acpi_os_map_memory(l1_dirbase, l1_hdr_size); | 223 | extlog_l1_hdr = acpi_os_map_iomem(l1_dirbase, l1_hdr_size); |
224 | l1_head = (struct extlog_l1_head *)extlog_l1_hdr; | 224 | l1_head = (struct extlog_l1_head *)extlog_l1_hdr; |
225 | l1_size = l1_head->total_len; | 225 | l1_size = l1_head->total_len; |
226 | l1_percpu_entry = l1_head->entries; | 226 | l1_percpu_entry = l1_head->entries; |
227 | elog_base = l1_head->elog_base; | 227 | elog_base = l1_head->elog_base; |
228 | elog_size = l1_head->elog_len; | 228 | elog_size = l1_head->elog_len; |
229 | acpi_os_unmap_memory(extlog_l1_hdr, l1_hdr_size); | 229 | acpi_os_unmap_iomem(extlog_l1_hdr, l1_hdr_size); |
230 | release_mem_region(l1_dirbase, l1_hdr_size); | 230 | release_mem_region(l1_dirbase, l1_hdr_size); |
231 | 231 | ||
232 | /* remap L1 header again based on completed information */ | 232 | /* remap L1 header again based on completed information */ |
@@ -237,7 +237,7 @@ static int __init extlog_init(void) | |||
237 | (unsigned long long)l1_dirbase + l1_size); | 237 | (unsigned long long)l1_dirbase + l1_size); |
238 | goto err; | 238 | goto err; |
239 | } | 239 | } |
240 | extlog_l1_addr = acpi_os_map_memory(l1_dirbase, l1_size); | 240 | extlog_l1_addr = acpi_os_map_iomem(l1_dirbase, l1_size); |
241 | l1_entry_base = (u64 *)((u8 *)extlog_l1_addr + l1_hdr_size); | 241 | l1_entry_base = (u64 *)((u8 *)extlog_l1_addr + l1_hdr_size); |
242 | 242 | ||
243 | /* remap elog table */ | 243 | /* remap elog table */ |
@@ -248,7 +248,7 @@ static int __init extlog_init(void) | |||
248 | (unsigned long long)elog_base + elog_size); | 248 | (unsigned long long)elog_base + elog_size); |
249 | goto err_release_l1_dir; | 249 | goto err_release_l1_dir; |
250 | } | 250 | } |
251 | elog_addr = acpi_os_map_memory(elog_base, elog_size); | 251 | elog_addr = acpi_os_map_iomem(elog_base, elog_size); |
252 | 252 | ||
253 | rc = -ENOMEM; | 253 | rc = -ENOMEM; |
254 | /* allocate buffer to save elog record */ | 254 | /* allocate buffer to save elog record */ |
@@ -270,11 +270,11 @@ static int __init extlog_init(void) | |||
270 | 270 | ||
271 | err_release_elog: | 271 | err_release_elog: |
272 | if (elog_addr) | 272 | if (elog_addr) |
273 | acpi_os_unmap_memory(elog_addr, elog_size); | 273 | acpi_os_unmap_iomem(elog_addr, elog_size); |
274 | release_mem_region(elog_base, elog_size); | 274 | release_mem_region(elog_base, elog_size); |
275 | err_release_l1_dir: | 275 | err_release_l1_dir: |
276 | if (extlog_l1_addr) | 276 | if (extlog_l1_addr) |
277 | acpi_os_unmap_memory(extlog_l1_addr, l1_size); | 277 | acpi_os_unmap_iomem(extlog_l1_addr, l1_size); |
278 | release_mem_region(l1_dirbase, l1_size); | 278 | release_mem_region(l1_dirbase, l1_size); |
279 | err: | 279 | err: |
280 | pr_warn(FW_BUG "Extended error log disabled because of problems parsing f/w tables\n"); | 280 | pr_warn(FW_BUG "Extended error log disabled because of problems parsing f/w tables\n"); |
@@ -287,9 +287,9 @@ static void __exit extlog_exit(void) | |||
287 | mce_unregister_decode_chain(&extlog_mce_dec); | 287 | mce_unregister_decode_chain(&extlog_mce_dec); |
288 | ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; | 288 | ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; |
289 | if (extlog_l1_addr) | 289 | if (extlog_l1_addr) |
290 | acpi_os_unmap_memory(extlog_l1_addr, l1_size); | 290 | acpi_os_unmap_iomem(extlog_l1_addr, l1_size); |
291 | if (elog_addr) | 291 | if (elog_addr) |
292 | acpi_os_unmap_memory(elog_addr, elog_size); | 292 | acpi_os_unmap_iomem(elog_addr, elog_size); |
293 | release_mem_region(elog_base, elog_size); | 293 | release_mem_region(elog_base, elog_size); |
294 | release_mem_region(l1_dirbase, l1_size); | 294 | release_mem_region(l1_dirbase, l1_size); |
295 | kfree(elog_buf); | 295 | kfree(elog_buf); |
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index d79c6d7f598e..63407d264885 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c | |||
@@ -19,15 +19,21 @@ | |||
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/platform_data/clk-lpss.h> | 20 | #include <linux/platform_data/clk-lpss.h> |
21 | #include <linux/pm_runtime.h> | 21 | #include <linux/pm_runtime.h> |
22 | #include <linux/delay.h> | ||
22 | 23 | ||
23 | #include "internal.h" | 24 | #include "internal.h" |
24 | 25 | ||
25 | ACPI_MODULE_NAME("acpi_lpss"); | 26 | ACPI_MODULE_NAME("acpi_lpss"); |
26 | 27 | ||
28 | #ifdef CONFIG_X86_INTEL_LPSS | ||
29 | |||
30 | #define LPSS_ADDR(desc) ((unsigned long)&desc) | ||
31 | |||
27 | #define LPSS_CLK_SIZE 0x04 | 32 | #define LPSS_CLK_SIZE 0x04 |
28 | #define LPSS_LTR_SIZE 0x18 | 33 | #define LPSS_LTR_SIZE 0x18 |
29 | 34 | ||
30 | /* Offsets relative to LPSS_PRIVATE_OFFSET */ | 35 | /* Offsets relative to LPSS_PRIVATE_OFFSET */ |
36 | #define LPSS_CLK_DIVIDER_DEF_MASK (BIT(1) | BIT(16)) | ||
31 | #define LPSS_GENERAL 0x08 | 37 | #define LPSS_GENERAL 0x08 |
32 | #define LPSS_GENERAL_LTR_MODE_SW BIT(2) | 38 | #define LPSS_GENERAL_LTR_MODE_SW BIT(2) |
33 | #define LPSS_GENERAL_UART_RTS_OVRD BIT(3) | 39 | #define LPSS_GENERAL_UART_RTS_OVRD BIT(3) |
@@ -43,6 +49,8 @@ ACPI_MODULE_NAME("acpi_lpss"); | |||
43 | #define LPSS_TX_INT 0x20 | 49 | #define LPSS_TX_INT 0x20 |
44 | #define LPSS_TX_INT_MASK BIT(1) | 50 | #define LPSS_TX_INT_MASK BIT(1) |
45 | 51 | ||
52 | #define LPSS_PRV_REG_COUNT 9 | ||
53 | |||
46 | struct lpss_shared_clock { | 54 | struct lpss_shared_clock { |
47 | const char *name; | 55 | const char *name; |
48 | unsigned long rate; | 56 | unsigned long rate; |
@@ -57,7 +65,9 @@ struct lpss_device_desc { | |||
57 | bool ltr_required; | 65 | bool ltr_required; |
58 | unsigned int prv_offset; | 66 | unsigned int prv_offset; |
59 | size_t prv_size_override; | 67 | size_t prv_size_override; |
68 | bool clk_divider; | ||
60 | bool clk_gate; | 69 | bool clk_gate; |
70 | bool save_ctx; | ||
61 | struct lpss_shared_clock *shared_clock; | 71 | struct lpss_shared_clock *shared_clock; |
62 | void (*setup)(struct lpss_private_data *pdata); | 72 | void (*setup)(struct lpss_private_data *pdata); |
63 | }; | 73 | }; |
@@ -72,6 +82,7 @@ struct lpss_private_data { | |||
72 | resource_size_t mmio_size; | 82 | resource_size_t mmio_size; |
73 | struct clk *clk; | 83 | struct clk *clk; |
74 | const struct lpss_device_desc *dev_desc; | 84 | const struct lpss_device_desc *dev_desc; |
85 | u32 prv_reg_ctx[LPSS_PRV_REG_COUNT]; | ||
75 | }; | 86 | }; |
76 | 87 | ||
77 | static void lpss_uart_setup(struct lpss_private_data *pdata) | 88 | static void lpss_uart_setup(struct lpss_private_data *pdata) |
@@ -92,6 +103,14 @@ static struct lpss_device_desc lpt_dev_desc = { | |||
92 | .clk_required = true, | 103 | .clk_required = true, |
93 | .prv_offset = 0x800, | 104 | .prv_offset = 0x800, |
94 | .ltr_required = true, | 105 | .ltr_required = true, |
106 | .clk_divider = true, | ||
107 | .clk_gate = true, | ||
108 | }; | ||
109 | |||
110 | static struct lpss_device_desc lpt_i2c_dev_desc = { | ||
111 | .clk_required = true, | ||
112 | .prv_offset = 0x800, | ||
113 | .ltr_required = true, | ||
95 | .clk_gate = true, | 114 | .clk_gate = true, |
96 | }; | 115 | }; |
97 | 116 | ||
@@ -99,6 +118,7 @@ static struct lpss_device_desc lpt_uart_dev_desc = { | |||
99 | .clk_required = true, | 118 | .clk_required = true, |
100 | .prv_offset = 0x800, | 119 | .prv_offset = 0x800, |
101 | .ltr_required = true, | 120 | .ltr_required = true, |
121 | .clk_divider = true, | ||
102 | .clk_gate = true, | 122 | .clk_gate = true, |
103 | .setup = lpss_uart_setup, | 123 | .setup = lpss_uart_setup, |
104 | }; | 124 | }; |
@@ -116,32 +136,25 @@ static struct lpss_shared_clock pwm_clock = { | |||
116 | 136 | ||
117 | static struct lpss_device_desc byt_pwm_dev_desc = { | 137 | static struct lpss_device_desc byt_pwm_dev_desc = { |
118 | .clk_required = true, | 138 | .clk_required = true, |
139 | .save_ctx = true, | ||
119 | .shared_clock = &pwm_clock, | 140 | .shared_clock = &pwm_clock, |
120 | }; | 141 | }; |
121 | 142 | ||
122 | static struct lpss_shared_clock uart_clock = { | ||
123 | .name = "uart_clk", | ||
124 | .rate = 44236800, | ||
125 | }; | ||
126 | |||
127 | static struct lpss_device_desc byt_uart_dev_desc = { | 143 | static struct lpss_device_desc byt_uart_dev_desc = { |
128 | .clk_required = true, | 144 | .clk_required = true, |
129 | .prv_offset = 0x800, | 145 | .prv_offset = 0x800, |
146 | .clk_divider = true, | ||
130 | .clk_gate = true, | 147 | .clk_gate = true, |
131 | .shared_clock = &uart_clock, | 148 | .save_ctx = true, |
132 | .setup = lpss_uart_setup, | 149 | .setup = lpss_uart_setup, |
133 | }; | 150 | }; |
134 | 151 | ||
135 | static struct lpss_shared_clock spi_clock = { | ||
136 | .name = "spi_clk", | ||
137 | .rate = 50000000, | ||
138 | }; | ||
139 | |||
140 | static struct lpss_device_desc byt_spi_dev_desc = { | 152 | static struct lpss_device_desc byt_spi_dev_desc = { |
141 | .clk_required = true, | 153 | .clk_required = true, |
142 | .prv_offset = 0x400, | 154 | .prv_offset = 0x400, |
155 | .clk_divider = true, | ||
143 | .clk_gate = true, | 156 | .clk_gate = true, |
144 | .shared_clock = &spi_clock, | 157 | .save_ctx = true, |
145 | }; | 158 | }; |
146 | 159 | ||
147 | static struct lpss_device_desc byt_sdio_dev_desc = { | 160 | static struct lpss_device_desc byt_sdio_dev_desc = { |
@@ -156,44 +169,53 @@ static struct lpss_shared_clock i2c_clock = { | |||
156 | static struct lpss_device_desc byt_i2c_dev_desc = { | 169 | static struct lpss_device_desc byt_i2c_dev_desc = { |
157 | .clk_required = true, | 170 | .clk_required = true, |
158 | .prv_offset = 0x800, | 171 | .prv_offset = 0x800, |
172 | .save_ctx = true, | ||
159 | .shared_clock = &i2c_clock, | 173 | .shared_clock = &i2c_clock, |
160 | }; | 174 | }; |
161 | 175 | ||
176 | #else | ||
177 | |||
178 | #define LPSS_ADDR(desc) (0UL) | ||
179 | |||
180 | #endif /* CONFIG_X86_INTEL_LPSS */ | ||
181 | |||
162 | static const struct acpi_device_id acpi_lpss_device_ids[] = { | 182 | static const struct acpi_device_id acpi_lpss_device_ids[] = { |
163 | /* Generic LPSS devices */ | 183 | /* Generic LPSS devices */ |
164 | { "INTL9C60", (unsigned long)&lpss_dma_desc }, | 184 | { "INTL9C60", LPSS_ADDR(lpss_dma_desc) }, |
165 | 185 | ||
166 | /* Lynxpoint LPSS devices */ | 186 | /* Lynxpoint LPSS devices */ |
167 | { "INT33C0", (unsigned long)&lpt_dev_desc }, | 187 | { "INT33C0", LPSS_ADDR(lpt_dev_desc) }, |
168 | { "INT33C1", (unsigned long)&lpt_dev_desc }, | 188 | { "INT33C1", LPSS_ADDR(lpt_dev_desc) }, |
169 | { "INT33C2", (unsigned long)&lpt_dev_desc }, | 189 | { "INT33C2", LPSS_ADDR(lpt_i2c_dev_desc) }, |
170 | { "INT33C3", (unsigned long)&lpt_dev_desc }, | 190 | { "INT33C3", LPSS_ADDR(lpt_i2c_dev_desc) }, |
171 | { "INT33C4", (unsigned long)&lpt_uart_dev_desc }, | 191 | { "INT33C4", LPSS_ADDR(lpt_uart_dev_desc) }, |
172 | { "INT33C5", (unsigned long)&lpt_uart_dev_desc }, | 192 | { "INT33C5", LPSS_ADDR(lpt_uart_dev_desc) }, |
173 | { "INT33C6", (unsigned long)&lpt_sdio_dev_desc }, | 193 | { "INT33C6", LPSS_ADDR(lpt_sdio_dev_desc) }, |
174 | { "INT33C7", }, | 194 | { "INT33C7", }, |
175 | 195 | ||
176 | /* BayTrail LPSS devices */ | 196 | /* BayTrail LPSS devices */ |
177 | { "80860F09", (unsigned long)&byt_pwm_dev_desc }, | 197 | { "80860F09", LPSS_ADDR(byt_pwm_dev_desc) }, |
178 | { "80860F0A", (unsigned long)&byt_uart_dev_desc }, | 198 | { "80860F0A", LPSS_ADDR(byt_uart_dev_desc) }, |
179 | { "80860F0E", (unsigned long)&byt_spi_dev_desc }, | 199 | { "80860F0E", LPSS_ADDR(byt_spi_dev_desc) }, |
180 | { "80860F14", (unsigned long)&byt_sdio_dev_desc }, | 200 | { "80860F14", LPSS_ADDR(byt_sdio_dev_desc) }, |
181 | { "80860F41", (unsigned long)&byt_i2c_dev_desc }, | 201 | { "80860F41", LPSS_ADDR(byt_i2c_dev_desc) }, |
182 | { "INT33B2", }, | 202 | { "INT33B2", }, |
183 | { "INT33FC", }, | 203 | { "INT33FC", }, |
184 | 204 | ||
185 | { "INT3430", (unsigned long)&lpt_dev_desc }, | 205 | { "INT3430", LPSS_ADDR(lpt_dev_desc) }, |
186 | { "INT3431", (unsigned long)&lpt_dev_desc }, | 206 | { "INT3431", LPSS_ADDR(lpt_dev_desc) }, |
187 | { "INT3432", (unsigned long)&lpt_dev_desc }, | 207 | { "INT3432", LPSS_ADDR(lpt_i2c_dev_desc) }, |
188 | { "INT3433", (unsigned long)&lpt_dev_desc }, | 208 | { "INT3433", LPSS_ADDR(lpt_i2c_dev_desc) }, |
189 | { "INT3434", (unsigned long)&lpt_uart_dev_desc }, | 209 | { "INT3434", LPSS_ADDR(lpt_uart_dev_desc) }, |
190 | { "INT3435", (unsigned long)&lpt_uart_dev_desc }, | 210 | { "INT3435", LPSS_ADDR(lpt_uart_dev_desc) }, |
191 | { "INT3436", (unsigned long)&lpt_sdio_dev_desc }, | 211 | { "INT3436", LPSS_ADDR(lpt_sdio_dev_desc) }, |
192 | { "INT3437", }, | 212 | { "INT3437", }, |
193 | 213 | ||
194 | { } | 214 | { } |
195 | }; | 215 | }; |
196 | 216 | ||
217 | #ifdef CONFIG_X86_INTEL_LPSS | ||
218 | |||
197 | static int is_memory(struct acpi_resource *res, void *not_used) | 219 | static int is_memory(struct acpi_resource *res, void *not_used) |
198 | { | 220 | { |
199 | struct resource r; | 221 | struct resource r; |
@@ -213,9 +235,11 @@ static int register_device_clock(struct acpi_device *adev, | |||
213 | { | 235 | { |
214 | const struct lpss_device_desc *dev_desc = pdata->dev_desc; | 236 | const struct lpss_device_desc *dev_desc = pdata->dev_desc; |
215 | struct lpss_shared_clock *shared_clock = dev_desc->shared_clock; | 237 | struct lpss_shared_clock *shared_clock = dev_desc->shared_clock; |
238 | const char *devname = dev_name(&adev->dev); | ||
216 | struct clk *clk = ERR_PTR(-ENODEV); | 239 | struct clk *clk = ERR_PTR(-ENODEV); |
217 | struct lpss_clk_data *clk_data; | 240 | struct lpss_clk_data *clk_data; |
218 | const char *parent; | 241 | const char *parent, *clk_name; |
242 | void __iomem *prv_base; | ||
219 | 243 | ||
220 | if (!lpss_clk_dev) | 244 | if (!lpss_clk_dev) |
221 | lpt_register_clock_device(); | 245 | lpt_register_clock_device(); |
@@ -226,7 +250,7 @@ static int register_device_clock(struct acpi_device *adev, | |||
226 | 250 | ||
227 | if (dev_desc->clkdev_name) { | 251 | if (dev_desc->clkdev_name) { |
228 | clk_register_clkdev(clk_data->clk, dev_desc->clkdev_name, | 252 | clk_register_clkdev(clk_data->clk, dev_desc->clkdev_name, |
229 | dev_name(&adev->dev)); | 253 | devname); |
230 | return 0; | 254 | return 0; |
231 | } | 255 | } |
232 | 256 | ||
@@ -235,6 +259,7 @@ static int register_device_clock(struct acpi_device *adev, | |||
235 | return -ENODATA; | 259 | return -ENODATA; |
236 | 260 | ||
237 | parent = clk_data->name; | 261 | parent = clk_data->name; |
262 | prv_base = pdata->mmio_base + dev_desc->prv_offset; | ||
238 | 263 | ||
239 | if (shared_clock) { | 264 | if (shared_clock) { |
240 | clk = shared_clock->clk; | 265 | clk = shared_clock->clk; |
@@ -248,16 +273,41 @@ static int register_device_clock(struct acpi_device *adev, | |||
248 | } | 273 | } |
249 | 274 | ||
250 | if (dev_desc->clk_gate) { | 275 | if (dev_desc->clk_gate) { |
251 | clk = clk_register_gate(NULL, dev_name(&adev->dev), parent, 0, | 276 | clk = clk_register_gate(NULL, devname, parent, 0, |
252 | pdata->mmio_base + dev_desc->prv_offset, | 277 | prv_base, 0, 0, NULL); |
253 | 0, 0, NULL); | 278 | parent = devname; |
254 | pdata->clk = clk; | 279 | } |
280 | |||
281 | if (dev_desc->clk_divider) { | ||
282 | /* Prevent division by zero */ | ||
283 | if (!readl(prv_base)) | ||
284 | writel(LPSS_CLK_DIVIDER_DEF_MASK, prv_base); | ||
285 | |||
286 | clk_name = kasprintf(GFP_KERNEL, "%s-div", devname); | ||
287 | if (!clk_name) | ||
288 | return -ENOMEM; | ||
289 | clk = clk_register_fractional_divider(NULL, clk_name, parent, | ||
290 | 0, prv_base, | ||
291 | 1, 15, 16, 15, 0, NULL); | ||
292 | parent = clk_name; | ||
293 | |||
294 | clk_name = kasprintf(GFP_KERNEL, "%s-update", devname); | ||
295 | if (!clk_name) { | ||
296 | kfree(parent); | ||
297 | return -ENOMEM; | ||
298 | } | ||
299 | clk = clk_register_gate(NULL, clk_name, parent, | ||
300 | CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, | ||
301 | prv_base, 31, 0, NULL); | ||
302 | kfree(parent); | ||
303 | kfree(clk_name); | ||
255 | } | 304 | } |
256 | 305 | ||
257 | if (IS_ERR(clk)) | 306 | if (IS_ERR(clk)) |
258 | return PTR_ERR(clk); | 307 | return PTR_ERR(clk); |
259 | 308 | ||
260 | clk_register_clkdev(clk, NULL, dev_name(&adev->dev)); | 309 | pdata->clk = clk; |
310 | clk_register_clkdev(clk, NULL, devname); | ||
261 | return 0; | 311 | return 0; |
262 | } | 312 | } |
263 | 313 | ||
@@ -268,12 +318,14 @@ static int acpi_lpss_create_device(struct acpi_device *adev, | |||
268 | struct lpss_private_data *pdata; | 318 | struct lpss_private_data *pdata; |
269 | struct resource_list_entry *rentry; | 319 | struct resource_list_entry *rentry; |
270 | struct list_head resource_list; | 320 | struct list_head resource_list; |
321 | struct platform_device *pdev; | ||
271 | int ret; | 322 | int ret; |
272 | 323 | ||
273 | dev_desc = (struct lpss_device_desc *)id->driver_data; | 324 | dev_desc = (struct lpss_device_desc *)id->driver_data; |
274 | if (!dev_desc) | 325 | if (!dev_desc) { |
275 | return acpi_create_platform_device(adev, id); | 326 | pdev = acpi_create_platform_device(adev); |
276 | 327 | return IS_ERR_OR_NULL(pdev) ? PTR_ERR(pdev) : 1; | |
328 | } | ||
277 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | 329 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); |
278 | if (!pdata) | 330 | if (!pdata) |
279 | return -ENOMEM; | 331 | return -ENOMEM; |
@@ -323,10 +375,13 @@ static int acpi_lpss_create_device(struct acpi_device *adev, | |||
323 | dev_desc->setup(pdata); | 375 | dev_desc->setup(pdata); |
324 | 376 | ||
325 | adev->driver_data = pdata; | 377 | adev->driver_data = pdata; |
326 | ret = acpi_create_platform_device(adev, id); | 378 | pdev = acpi_create_platform_device(adev); |
327 | if (ret > 0) | 379 | if (!IS_ERR_OR_NULL(pdev)) { |
328 | return ret; | 380 | device_enable_async_suspend(&pdev->dev); |
381 | return 1; | ||
382 | } | ||
329 | 383 | ||
384 | ret = PTR_ERR(pdev); | ||
330 | adev->driver_data = NULL; | 385 | adev->driver_data = NULL; |
331 | 386 | ||
332 | err_out: | 387 | err_out: |
@@ -450,6 +505,126 @@ static void acpi_lpss_set_ltr(struct device *dev, s32 val) | |||
450 | } | 505 | } |
451 | } | 506 | } |
452 | 507 | ||
508 | #ifdef CONFIG_PM | ||
509 | /** | ||
510 | * acpi_lpss_save_ctx() - Save the private registers of LPSS device | ||
511 | * @dev: LPSS device | ||
512 | * | ||
513 | * Most LPSS devices have private registers which may loose their context when | ||
514 | * the device is powered down. acpi_lpss_save_ctx() saves those registers into | ||
515 | * prv_reg_ctx array. | ||
516 | */ | ||
517 | static void acpi_lpss_save_ctx(struct device *dev) | ||
518 | { | ||
519 | struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); | ||
520 | unsigned int i; | ||
521 | |||
522 | for (i = 0; i < LPSS_PRV_REG_COUNT; i++) { | ||
523 | unsigned long offset = i * sizeof(u32); | ||
524 | |||
525 | pdata->prv_reg_ctx[i] = __lpss_reg_read(pdata, offset); | ||
526 | dev_dbg(dev, "saving 0x%08x from LPSS reg at offset 0x%02lx\n", | ||
527 | pdata->prv_reg_ctx[i], offset); | ||
528 | } | ||
529 | } | ||
530 | |||
531 | /** | ||
532 | * acpi_lpss_restore_ctx() - Restore the private registers of LPSS device | ||
533 | * @dev: LPSS device | ||
534 | * | ||
535 | * Restores the registers that were previously stored with acpi_lpss_save_ctx(). | ||
536 | */ | ||
537 | static void acpi_lpss_restore_ctx(struct device *dev) | ||
538 | { | ||
539 | struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); | ||
540 | unsigned int i; | ||
541 | |||
542 | /* | ||
543 | * The following delay is needed or the subsequent write operations may | ||
544 | * fail. The LPSS devices are actually PCI devices and the PCI spec | ||
545 | * expects 10ms delay before the device can be accessed after D3 to D0 | ||
546 | * transition. | ||
547 | */ | ||
548 | msleep(10); | ||
549 | |||
550 | for (i = 0; i < LPSS_PRV_REG_COUNT; i++) { | ||
551 | unsigned long offset = i * sizeof(u32); | ||
552 | |||
553 | __lpss_reg_write(pdata->prv_reg_ctx[i], pdata, offset); | ||
554 | dev_dbg(dev, "restoring 0x%08x to LPSS reg at offset 0x%02lx\n", | ||
555 | pdata->prv_reg_ctx[i], offset); | ||
556 | } | ||
557 | } | ||
558 | |||
559 | #ifdef CONFIG_PM_SLEEP | ||
560 | static int acpi_lpss_suspend_late(struct device *dev) | ||
561 | { | ||
562 | int ret = pm_generic_suspend_late(dev); | ||
563 | |||
564 | if (ret) | ||
565 | return ret; | ||
566 | |||
567 | acpi_lpss_save_ctx(dev); | ||
568 | return acpi_dev_suspend_late(dev); | ||
569 | } | ||
570 | |||
571 | static int acpi_lpss_restore_early(struct device *dev) | ||
572 | { | ||
573 | int ret = acpi_dev_resume_early(dev); | ||
574 | |||
575 | if (ret) | ||
576 | return ret; | ||
577 | |||
578 | acpi_lpss_restore_ctx(dev); | ||
579 | return pm_generic_resume_early(dev); | ||
580 | } | ||
581 | #endif /* CONFIG_PM_SLEEP */ | ||
582 | |||
583 | #ifdef CONFIG_PM_RUNTIME | ||
584 | static int acpi_lpss_runtime_suspend(struct device *dev) | ||
585 | { | ||
586 | int ret = pm_generic_runtime_suspend(dev); | ||
587 | |||
588 | if (ret) | ||
589 | return ret; | ||
590 | |||
591 | acpi_lpss_save_ctx(dev); | ||
592 | return acpi_dev_runtime_suspend(dev); | ||
593 | } | ||
594 | |||
595 | static int acpi_lpss_runtime_resume(struct device *dev) | ||
596 | { | ||
597 | int ret = acpi_dev_runtime_resume(dev); | ||
598 | |||
599 | if (ret) | ||
600 | return ret; | ||
601 | |||
602 | acpi_lpss_restore_ctx(dev); | ||
603 | return pm_generic_runtime_resume(dev); | ||
604 | } | ||
605 | #endif /* CONFIG_PM_RUNTIME */ | ||
606 | #endif /* CONFIG_PM */ | ||
607 | |||
608 | static struct dev_pm_domain acpi_lpss_pm_domain = { | ||
609 | .ops = { | ||
610 | #ifdef CONFIG_PM_SLEEP | ||
611 | .suspend_late = acpi_lpss_suspend_late, | ||
612 | .restore_early = acpi_lpss_restore_early, | ||
613 | .prepare = acpi_subsys_prepare, | ||
614 | .complete = acpi_subsys_complete, | ||
615 | .suspend = acpi_subsys_suspend, | ||
616 | .resume_early = acpi_subsys_resume_early, | ||
617 | .freeze = acpi_subsys_freeze, | ||
618 | .poweroff = acpi_subsys_suspend, | ||
619 | .poweroff_late = acpi_subsys_suspend_late, | ||
620 | #endif | ||
621 | #ifdef CONFIG_PM_RUNTIME | ||
622 | .runtime_suspend = acpi_lpss_runtime_suspend, | ||
623 | .runtime_resume = acpi_lpss_runtime_resume, | ||
624 | #endif | ||
625 | }, | ||
626 | }; | ||
627 | |||
453 | static int acpi_lpss_platform_notify(struct notifier_block *nb, | 628 | static int acpi_lpss_platform_notify(struct notifier_block *nb, |
454 | unsigned long action, void *data) | 629 | unsigned long action, void *data) |
455 | { | 630 | { |
@@ -457,7 +632,6 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb, | |||
457 | struct lpss_private_data *pdata; | 632 | struct lpss_private_data *pdata; |
458 | struct acpi_device *adev; | 633 | struct acpi_device *adev; |
459 | const struct acpi_device_id *id; | 634 | const struct acpi_device_id *id; |
460 | int ret = 0; | ||
461 | 635 | ||
462 | id = acpi_match_device(acpi_lpss_device_ids, &pdev->dev); | 636 | id = acpi_match_device(acpi_lpss_device_ids, &pdev->dev); |
463 | if (!id || !id->driver_data) | 637 | if (!id || !id->driver_data) |
@@ -467,7 +641,7 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb, | |||
467 | return 0; | 641 | return 0; |
468 | 642 | ||
469 | pdata = acpi_driver_data(adev); | 643 | pdata = acpi_driver_data(adev); |
470 | if (!pdata || !pdata->mmio_base || !pdata->dev_desc->ltr_required) | 644 | if (!pdata || !pdata->mmio_base) |
471 | return 0; | 645 | return 0; |
472 | 646 | ||
473 | if (pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) { | 647 | if (pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) { |
@@ -475,12 +649,27 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb, | |||
475 | return 0; | 649 | return 0; |
476 | } | 650 | } |
477 | 651 | ||
478 | if (action == BUS_NOTIFY_ADD_DEVICE) | 652 | switch (action) { |
479 | ret = sysfs_create_group(&pdev->dev.kobj, &lpss_attr_group); | 653 | case BUS_NOTIFY_BOUND_DRIVER: |
480 | else if (action == BUS_NOTIFY_DEL_DEVICE) | 654 | if (pdata->dev_desc->save_ctx) |
481 | sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group); | 655 | pdev->dev.pm_domain = &acpi_lpss_pm_domain; |
656 | break; | ||
657 | case BUS_NOTIFY_UNBOUND_DRIVER: | ||
658 | if (pdata->dev_desc->save_ctx) | ||
659 | pdev->dev.pm_domain = NULL; | ||
660 | break; | ||
661 | case BUS_NOTIFY_ADD_DEVICE: | ||
662 | if (pdata->dev_desc->ltr_required) | ||
663 | return sysfs_create_group(&pdev->dev.kobj, | ||
664 | &lpss_attr_group); | ||
665 | case BUS_NOTIFY_DEL_DEVICE: | ||
666 | if (pdata->dev_desc->ltr_required) | ||
667 | sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group); | ||
668 | default: | ||
669 | break; | ||
670 | } | ||
482 | 671 | ||
483 | return ret; | 672 | return 0; |
484 | } | 673 | } |
485 | 674 | ||
486 | static struct notifier_block acpi_lpss_nb = { | 675 | static struct notifier_block acpi_lpss_nb = { |
@@ -519,3 +708,16 @@ void __init acpi_lpss_init(void) | |||
519 | acpi_scan_add_handler(&lpss_handler); | 708 | acpi_scan_add_handler(&lpss_handler); |
520 | } | 709 | } |
521 | } | 710 | } |
711 | |||
712 | #else | ||
713 | |||
714 | static struct acpi_scan_handler lpss_handler = { | ||
715 | .ids = acpi_lpss_device_ids, | ||
716 | }; | ||
717 | |||
718 | void __init acpi_lpss_init(void) | ||
719 | { | ||
720 | acpi_scan_add_handler(&lpss_handler); | ||
721 | } | ||
722 | |||
723 | #endif /* CONFIG_X86_INTEL_LPSS */ | ||
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index b67be85ff0fc..23e2319ead41 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -44,6 +44,13 @@ | |||
44 | 44 | ||
45 | ACPI_MODULE_NAME("acpi_memhotplug"); | 45 | ACPI_MODULE_NAME("acpi_memhotplug"); |
46 | 46 | ||
47 | static const struct acpi_device_id memory_device_ids[] = { | ||
48 | {ACPI_MEMORY_DEVICE_HID, 0}, | ||
49 | {"", 0}, | ||
50 | }; | ||
51 | |||
52 | #ifdef CONFIG_ACPI_HOTPLUG_MEMORY | ||
53 | |||
47 | /* Memory Device States */ | 54 | /* Memory Device States */ |
48 | #define MEMORY_INVALID_STATE 0 | 55 | #define MEMORY_INVALID_STATE 0 |
49 | #define MEMORY_POWER_ON_STATE 1 | 56 | #define MEMORY_POWER_ON_STATE 1 |
@@ -53,11 +60,6 @@ static int acpi_memory_device_add(struct acpi_device *device, | |||
53 | const struct acpi_device_id *not_used); | 60 | const struct acpi_device_id *not_used); |
54 | static void acpi_memory_device_remove(struct acpi_device *device); | 61 | static void acpi_memory_device_remove(struct acpi_device *device); |
55 | 62 | ||
56 | static const struct acpi_device_id memory_device_ids[] = { | ||
57 | {ACPI_MEMORY_DEVICE_HID, 0}, | ||
58 | {"", 0}, | ||
59 | }; | ||
60 | |||
61 | static struct acpi_scan_handler memory_device_handler = { | 63 | static struct acpi_scan_handler memory_device_handler = { |
62 | .ids = memory_device_ids, | 64 | .ids = memory_device_ids, |
63 | .attach = acpi_memory_device_add, | 65 | .attach = acpi_memory_device_add, |
@@ -364,9 +366,11 @@ static bool __initdata acpi_no_memhotplug; | |||
364 | 366 | ||
365 | void __init acpi_memory_hotplug_init(void) | 367 | void __init acpi_memory_hotplug_init(void) |
366 | { | 368 | { |
367 | if (acpi_no_memhotplug) | 369 | if (acpi_no_memhotplug) { |
370 | memory_device_handler.attach = NULL; | ||
371 | acpi_scan_add_handler(&memory_device_handler); | ||
368 | return; | 372 | return; |
369 | 373 | } | |
370 | acpi_scan_add_handler_with_hotplug(&memory_device_handler, "memory"); | 374 | acpi_scan_add_handler_with_hotplug(&memory_device_handler, "memory"); |
371 | } | 375 | } |
372 | 376 | ||
@@ -376,3 +380,16 @@ static int __init disable_acpi_memory_hotplug(char *str) | |||
376 | return 1; | 380 | return 1; |
377 | } | 381 | } |
378 | __setup("acpi_no_memhotplug", disable_acpi_memory_hotplug); | 382 | __setup("acpi_no_memhotplug", disable_acpi_memory_hotplug); |
383 | |||
384 | #else | ||
385 | |||
386 | static struct acpi_scan_handler memory_device_handler = { | ||
387 | .ids = memory_device_ids, | ||
388 | }; | ||
389 | |||
390 | void __init acpi_memory_hotplug_init(void) | ||
391 | { | ||
392 | acpi_scan_add_handler(&memory_device_handler); | ||
393 | } | ||
394 | |||
395 | #endif /* CONFIG_ACPI_HOTPLUG_MEMORY */ | ||
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 37d73024b82e..f148a0580e04 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
@@ -156,12 +156,13 @@ static int power_saving_thread(void *data) | |||
156 | 156 | ||
157 | while (!kthread_should_stop()) { | 157 | while (!kthread_should_stop()) { |
158 | int cpu; | 158 | int cpu; |
159 | u64 expire_time; | 159 | unsigned long expire_time; |
160 | 160 | ||
161 | try_to_freeze(); | 161 | try_to_freeze(); |
162 | 162 | ||
163 | /* round robin to cpus */ | 163 | /* round robin to cpus */ |
164 | if (last_jiffies + round_robin_time * HZ < jiffies) { | 164 | expire_time = last_jiffies + round_robin_time * HZ; |
165 | if (time_before(expire_time, jiffies)) { | ||
165 | last_jiffies = jiffies; | 166 | last_jiffies = jiffies; |
166 | round_robin_cpu(tsk_index); | 167 | round_robin_cpu(tsk_index); |
167 | } | 168 | } |
@@ -200,7 +201,7 @@ static int power_saving_thread(void *data) | |||
200 | CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); | 201 | CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); |
201 | local_irq_enable(); | 202 | local_irq_enable(); |
202 | 203 | ||
203 | if (jiffies > expire_time) { | 204 | if (time_before(expire_time, jiffies)) { |
204 | do_sleep = 1; | 205 | do_sleep = 1; |
205 | break; | 206 | break; |
206 | } | 207 | } |
@@ -215,8 +216,15 @@ static int power_saving_thread(void *data) | |||
215 | * borrow CPU time from this CPU and cause RT task use > 95% | 216 | * borrow CPU time from this CPU and cause RT task use > 95% |
216 | * CPU time. To make 'avoid starvation' work, takes a nap here. | 217 | * CPU time. To make 'avoid starvation' work, takes a nap here. |
217 | */ | 218 | */ |
218 | if (do_sleep) | 219 | if (unlikely(do_sleep)) |
219 | schedule_timeout_killable(HZ * idle_pct / 100); | 220 | schedule_timeout_killable(HZ * idle_pct / 100); |
221 | |||
222 | /* If an external event has set the need_resched flag, then | ||
223 | * we need to deal with it, or this loop will continue to | ||
224 | * spin without calling __mwait(). | ||
225 | */ | ||
226 | if (unlikely(need_resched())) | ||
227 | schedule(); | ||
220 | } | 228 | } |
221 | 229 | ||
222 | exit_round_robin(tsk_index); | 230 | exit_round_robin(tsk_index); |
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 1d4950388fa1..2bf9082f7523 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c | |||
@@ -22,27 +22,16 @@ | |||
22 | 22 | ||
23 | ACPI_MODULE_NAME("platform"); | 23 | ACPI_MODULE_NAME("platform"); |
24 | 24 | ||
25 | /* | 25 | static const struct acpi_device_id forbidden_id_list[] = { |
26 | * The following ACPI IDs are known to be suitable for representing as | 26 | {"PNP0000", 0}, /* PIC */ |
27 | * platform devices. | 27 | {"PNP0100", 0}, /* Timer */ |
28 | */ | 28 | {"PNP0200", 0}, /* AT DMA Controller */ |
29 | static const struct acpi_device_id acpi_platform_device_ids[] = { | 29 | {"", 0}, |
30 | |||
31 | { "PNP0D40" }, | ||
32 | { "VPC2004" }, | ||
33 | { "BCM4752" }, | ||
34 | |||
35 | /* Intel Smart Sound Technology */ | ||
36 | { "INT33C8" }, | ||
37 | { "80860F28" }, | ||
38 | |||
39 | { } | ||
40 | }; | 30 | }; |
41 | 31 | ||
42 | /** | 32 | /** |
43 | * acpi_create_platform_device - Create platform device for ACPI device node | 33 | * acpi_create_platform_device - Create platform device for ACPI device node |
44 | * @adev: ACPI device node to create a platform device for. | 34 | * @adev: ACPI device node to create a platform device for. |
45 | * @id: ACPI device ID used to match @adev. | ||
46 | * | 35 | * |
47 | * Check if the given @adev can be represented as a platform device and, if | 36 | * Check if the given @adev can be represented as a platform device and, if |
48 | * that's the case, create and register a platform device, populate its common | 37 | * that's the case, create and register a platform device, populate its common |
@@ -50,8 +39,7 @@ static const struct acpi_device_id acpi_platform_device_ids[] = { | |||
50 | * | 39 | * |
51 | * Name of the platform device will be the same as @adev's. | 40 | * Name of the platform device will be the same as @adev's. |
52 | */ | 41 | */ |
53 | int acpi_create_platform_device(struct acpi_device *adev, | 42 | struct platform_device *acpi_create_platform_device(struct acpi_device *adev) |
54 | const struct acpi_device_id *id) | ||
55 | { | 43 | { |
56 | struct platform_device *pdev = NULL; | 44 | struct platform_device *pdev = NULL; |
57 | struct acpi_device *acpi_parent; | 45 | struct acpi_device *acpi_parent; |
@@ -63,19 +51,22 @@ int acpi_create_platform_device(struct acpi_device *adev, | |||
63 | 51 | ||
64 | /* If the ACPI node already has a physical device attached, skip it. */ | 52 | /* If the ACPI node already has a physical device attached, skip it. */ |
65 | if (adev->physical_node_count) | 53 | if (adev->physical_node_count) |
66 | return 0; | 54 | return NULL; |
55 | |||
56 | if (!acpi_match_device_ids(adev, forbidden_id_list)) | ||
57 | return ERR_PTR(-EINVAL); | ||
67 | 58 | ||
68 | INIT_LIST_HEAD(&resource_list); | 59 | INIT_LIST_HEAD(&resource_list); |
69 | count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); | 60 | count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); |
70 | if (count < 0) { | 61 | if (count < 0) { |
71 | return 0; | 62 | return NULL; |
72 | } else if (count > 0) { | 63 | } else if (count > 0) { |
73 | resources = kmalloc(count * sizeof(struct resource), | 64 | resources = kmalloc(count * sizeof(struct resource), |
74 | GFP_KERNEL); | 65 | GFP_KERNEL); |
75 | if (!resources) { | 66 | if (!resources) { |
76 | dev_err(&adev->dev, "No memory for resources\n"); | 67 | dev_err(&adev->dev, "No memory for resources\n"); |
77 | acpi_dev_free_resource_list(&resource_list); | 68 | acpi_dev_free_resource_list(&resource_list); |
78 | return -ENOMEM; | 69 | return ERR_PTR(-ENOMEM); |
79 | } | 70 | } |
80 | count = 0; | 71 | count = 0; |
81 | list_for_each_entry(rentry, &resource_list, node) | 72 | list_for_each_entry(rentry, &resource_list, node) |
@@ -112,25 +103,13 @@ int acpi_create_platform_device(struct acpi_device *adev, | |||
112 | pdevinfo.num_res = count; | 103 | pdevinfo.num_res = count; |
113 | pdevinfo.acpi_node.companion = adev; | 104 | pdevinfo.acpi_node.companion = adev; |
114 | pdev = platform_device_register_full(&pdevinfo); | 105 | pdev = platform_device_register_full(&pdevinfo); |
115 | if (IS_ERR(pdev)) { | 106 | if (IS_ERR(pdev)) |
116 | dev_err(&adev->dev, "platform device creation failed: %ld\n", | 107 | dev_err(&adev->dev, "platform device creation failed: %ld\n", |
117 | PTR_ERR(pdev)); | 108 | PTR_ERR(pdev)); |
118 | pdev = NULL; | 109 | else |
119 | } else { | ||
120 | dev_dbg(&adev->dev, "created platform device %s\n", | 110 | dev_dbg(&adev->dev, "created platform device %s\n", |
121 | dev_name(&pdev->dev)); | 111 | dev_name(&pdev->dev)); |
122 | } | ||
123 | 112 | ||
124 | kfree(resources); | 113 | kfree(resources); |
125 | return 1; | 114 | return pdev; |
126 | } | ||
127 | |||
128 | static struct acpi_scan_handler platform_handler = { | ||
129 | .ids = acpi_platform_device_ids, | ||
130 | .attach = acpi_create_platform_device, | ||
131 | }; | ||
132 | |||
133 | void __init acpi_platform_init(void) | ||
134 | { | ||
135 | acpi_scan_add_handler(&platform_handler); | ||
136 | } | 115 | } |
diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c new file mode 100644 index 000000000000..6703c1fd993a --- /dev/null +++ b/drivers/acpi/acpi_pnp.c | |||
@@ -0,0 +1,395 @@ | |||
1 | /* | ||
2 | * ACPI support for PNP bus type | ||
3 | * | ||
4 | * Copyright (C) 2014, Intel Corporation | ||
5 | * Authors: Zhang Rui <rui.zhang@intel.com> | ||
6 | * Rafael J. Wysocki <rafael.j.wysocki@intel.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/acpi.h> | ||
14 | #include <linux/module.h> | ||
15 | |||
16 | static const struct acpi_device_id acpi_pnp_device_ids[] = { | ||
17 | /* pata_isapnp */ | ||
18 | {"PNP0600"}, /* Generic ESDI/IDE/ATA compatible hard disk controller */ | ||
19 | /* floppy */ | ||
20 | {"PNP0700"}, | ||
21 | /* ipmi_si */ | ||
22 | {"IPI0001"}, | ||
23 | /* tpm_inf_pnp */ | ||
24 | {"IFX0101"}, /* Infineon TPMs */ | ||
25 | {"IFX0102"}, /* Infineon TPMs */ | ||
26 | /*tpm_tis */ | ||
27 | {"PNP0C31"}, /* TPM */ | ||
28 | {"ATM1200"}, /* Atmel */ | ||
29 | {"IFX0102"}, /* Infineon */ | ||
30 | {"BCM0101"}, /* Broadcom */ | ||
31 | {"BCM0102"}, /* Broadcom */ | ||
32 | {"NSC1200"}, /* National */ | ||
33 | {"ICO0102"}, /* Intel */ | ||
34 | /* ide */ | ||
35 | {"PNP0600"}, /* Generic ESDI/IDE/ATA compatible hard disk controller */ | ||
36 | /* ns558 */ | ||
37 | {"ASB16fd"}, /* AdLib NSC16 */ | ||
38 | {"AZT3001"}, /* AZT1008 */ | ||
39 | {"CDC0001"}, /* Opl3-SAx */ | ||
40 | {"CSC0001"}, /* CS4232 */ | ||
41 | {"CSC000f"}, /* CS4236 */ | ||
42 | {"CSC0101"}, /* CS4327 */ | ||
43 | {"CTL7001"}, /* SB16 */ | ||
44 | {"CTL7002"}, /* AWE64 */ | ||
45 | {"CTL7005"}, /* Vibra16 */ | ||
46 | {"ENS2020"}, /* SoundscapeVIVO */ | ||
47 | {"ESS0001"}, /* ES1869 */ | ||
48 | {"ESS0005"}, /* ES1878 */ | ||
49 | {"ESS6880"}, /* ES688 */ | ||
50 | {"IBM0012"}, /* CS4232 */ | ||
51 | {"OPT0001"}, /* OPTi Audio16 */ | ||
52 | {"YMH0006"}, /* Opl3-SA */ | ||
53 | {"YMH0022"}, /* Opl3-SAx */ | ||
54 | {"PNPb02f"}, /* Generic */ | ||
55 | /* i8042 kbd */ | ||
56 | {"PNP0300"}, | ||
57 | {"PNP0301"}, | ||
58 | {"PNP0302"}, | ||
59 | {"PNP0303"}, | ||
60 | {"PNP0304"}, | ||
61 | {"PNP0305"}, | ||
62 | {"PNP0306"}, | ||
63 | {"PNP0309"}, | ||
64 | {"PNP030a"}, | ||
65 | {"PNP030b"}, | ||
66 | {"PNP0320"}, | ||
67 | {"PNP0343"}, | ||
68 | {"PNP0344"}, | ||
69 | {"PNP0345"}, | ||
70 | {"CPQA0D7"}, | ||
71 | /* i8042 aux */ | ||
72 | {"AUI0200"}, | ||
73 | {"FJC6000"}, | ||
74 | {"FJC6001"}, | ||
75 | {"PNP0f03"}, | ||
76 | {"PNP0f0b"}, | ||
77 | {"PNP0f0e"}, | ||
78 | {"PNP0f12"}, | ||
79 | {"PNP0f13"}, | ||
80 | {"PNP0f19"}, | ||
81 | {"PNP0f1c"}, | ||
82 | {"SYN0801"}, | ||
83 | /* fcpnp */ | ||
84 | {"AVM0900"}, | ||
85 | /* radio-cadet */ | ||
86 | {"MSM0c24"}, /* ADS Cadet AM/FM Radio Card */ | ||
87 | /* radio-gemtek */ | ||
88 | {"ADS7183"}, /* AOpen FX-3D/Pro Radio */ | ||
89 | /* radio-sf16fmr2 */ | ||
90 | {"MFRad13"}, /* tuner subdevice of SF16-FMD2 */ | ||
91 | /* ene_ir */ | ||
92 | {"ENE0100"}, | ||
93 | {"ENE0200"}, | ||
94 | {"ENE0201"}, | ||
95 | {"ENE0202"}, | ||
96 | /* fintek-cir */ | ||
97 | {"FIT0002"}, /* CIR */ | ||
98 | /* ite-cir */ | ||
99 | {"ITE8704"}, /* Default model */ | ||
100 | {"ITE8713"}, /* CIR found in EEEBox 1501U */ | ||
101 | {"ITE8708"}, /* Bridged IT8512 */ | ||
102 | {"ITE8709"}, /* SRAM-Bridged IT8512 */ | ||
103 | /* nuvoton-cir */ | ||
104 | {"WEC0530"}, /* CIR */ | ||
105 | {"NTN0530"}, /* CIR for new chip's pnp id */ | ||
106 | /* Winbond CIR */ | ||
107 | {"WEC1022"}, | ||
108 | /* wbsd */ | ||
109 | {"WEC0517"}, | ||
110 | {"WEC0518"}, | ||
111 | /* Winbond CIR */ | ||
112 | {"TCM5090"}, /* 3Com Etherlink III (TP) */ | ||
113 | {"TCM5091"}, /* 3Com Etherlink III */ | ||
114 | {"TCM5094"}, /* 3Com Etherlink III (combo) */ | ||
115 | {"TCM5095"}, /* 3Com Etherlink III (TPO) */ | ||
116 | {"TCM5098"}, /* 3Com Etherlink III (TPC) */ | ||
117 | {"PNP80f7"}, /* 3Com Etherlink III compatible */ | ||
118 | {"PNP80f8"}, /* 3Com Etherlink III compatible */ | ||
119 | /* nsc-ircc */ | ||
120 | {"NSC6001"}, | ||
121 | {"HWPC224"}, | ||
122 | {"IBM0071"}, | ||
123 | /* smsc-ircc2 */ | ||
124 | {"SMCf010"}, | ||
125 | /* sb1000 */ | ||
126 | {"GIC1000"}, | ||
127 | /* parport_pc */ | ||
128 | {"PNP0400"}, /* Standard LPT Printer Port */ | ||
129 | {"PNP0401"}, /* ECP Printer Port */ | ||
130 | /* apple-gmux */ | ||
131 | {"APP000B"}, | ||
132 | /* fujitsu-laptop.c */ | ||
133 | {"FUJ02bf"}, | ||
134 | {"FUJ02B1"}, | ||
135 | {"FUJ02E3"}, | ||
136 | /* system */ | ||
137 | {"PNP0c02"}, /* General ID for reserving resources */ | ||
138 | {"PNP0c01"}, /* memory controller */ | ||
139 | /* rtc_cmos */ | ||
140 | {"PNP0b00"}, | ||
141 | {"PNP0b01"}, | ||
142 | {"PNP0b02"}, | ||
143 | /* c6xdigio */ | ||
144 | {"PNP0400"}, /* Standard LPT Printer Port */ | ||
145 | {"PNP0401"}, /* ECP Printer Port */ | ||
146 | /* ni_atmio.c */ | ||
147 | {"NIC1900"}, | ||
148 | {"NIC2400"}, | ||
149 | {"NIC2500"}, | ||
150 | {"NIC2600"}, | ||
151 | {"NIC2700"}, | ||
152 | /* serial */ | ||
153 | {"AAC000F"}, /* Archtek America Corp. Archtek SmartLink Modem 3334BT Plug & Play */ | ||
154 | {"ADC0001"}, /* Anchor Datacomm BV. SXPro 144 External Data Fax Modem Plug & Play */ | ||
155 | {"ADC0002"}, /* SXPro 288 External Data Fax Modem Plug & Play */ | ||
156 | {"AEI0250"}, /* PROLiNK 1456VH ISA PnP K56flex Fax Modem */ | ||
157 | {"AEI1240"}, /* Actiontec ISA PNP 56K X2 Fax Modem */ | ||
158 | {"AKY1021"}, /* Rockwell 56K ACF II Fax+Data+Voice Modem */ | ||
159 | {"AZT4001"}, /* AZT3005 PnP SOUND DEVICE */ | ||
160 | {"BDP3336"}, /* Best Data Products Inc. Smart One 336F PnP Modem */ | ||
161 | {"BRI0A49"}, /* Boca Complete Ofc Communicator 14.4 Data-FAX */ | ||
162 | {"BRI1400"}, /* Boca Research 33,600 ACF Modem */ | ||
163 | {"BRI3400"}, /* Boca 33.6 Kbps Internal FD34FSVD */ | ||
164 | {"BRI0A49"}, /* Boca 33.6 Kbps Internal FD34FSVD */ | ||
165 | {"BDP3336"}, /* Best Data Products Inc. Smart One 336F PnP Modem */ | ||
166 | {"CPI4050"}, /* Computer Peripherals Inc. EuroViVa CommCenter-33.6 SP PnP */ | ||
167 | {"CTL3001"}, /* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */ | ||
168 | {"CTL3011"}, /* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */ | ||
169 | {"DAV0336"}, /* Davicom ISA 33.6K Modem */ | ||
170 | {"DMB1032"}, /* Creative Modem Blaster Flash56 DI5601-1 */ | ||
171 | {"DMB2001"}, /* Creative Modem Blaster V.90 DI5660 */ | ||
172 | {"ETT0002"}, /* E-Tech CyberBULLET PC56RVP */ | ||
173 | {"FUJ0202"}, /* Fujitsu 33600 PnP-I2 R Plug & Play */ | ||
174 | {"FUJ0205"}, /* Fujitsu FMV-FX431 Plug & Play */ | ||
175 | {"FUJ0206"}, /* Fujitsu 33600 PnP-I4 R Plug & Play */ | ||
176 | {"FUJ0209"}, /* Fujitsu Fax Voice 33600 PNP-I5 R Plug & Play */ | ||
177 | {"GVC000F"}, /* Archtek SmartLink Modem 3334BT Plug & Play */ | ||
178 | {"GVC0303"}, /* Archtek SmartLink Modem 3334BRV 33.6K Data Fax Voice */ | ||
179 | {"HAY0001"}, /* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */ | ||
180 | {"HAY000C"}, /* Hayes Optima 336 V.34 + FAX + Voice PnP */ | ||
181 | {"HAY000D"}, /* Hayes Optima 336B V.34 + FAX + Voice PnP */ | ||
182 | {"HAY5670"}, /* Hayes Accura 56K Ext Fax Modem PnP */ | ||
183 | {"HAY5674"}, /* Hayes Accura 56K Ext Fax Modem PnP */ | ||
184 | {"HAY5675"}, /* Hayes Accura 56K Fax Modem PnP */ | ||
185 | {"HAYF000"}, /* Hayes 288, V.34 + FAX */ | ||
186 | {"HAYF001"}, /* Hayes Optima 288 V.34 + FAX + Voice, Plug & Play */ | ||
187 | {"IBM0033"}, /* IBM Thinkpad 701 Internal Modem Voice */ | ||
188 | {"PNP4972"}, /* Intermec CV60 touchscreen port */ | ||
189 | {"IXDC801"}, /* Intertex 28k8 33k6 Voice EXT PnP */ | ||
190 | {"IXDC901"}, /* Intertex 33k6 56k Voice EXT PnP */ | ||
191 | {"IXDD801"}, /* Intertex 28k8 33k6 Voice SP EXT PnP */ | ||
192 | {"IXDD901"}, /* Intertex 33k6 56k Voice SP EXT PnP */ | ||
193 | {"IXDF401"}, /* Intertex 28k8 33k6 Voice SP INT PnP */ | ||
194 | {"IXDF801"}, /* Intertex 28k8 33k6 Voice SP EXT PnP */ | ||
195 | {"IXDF901"}, /* Intertex 33k6 56k Voice SP EXT PnP */ | ||
196 | {"KOR4522"}, /* KORTEX 28800 Externe PnP */ | ||
197 | {"KORF661"}, /* KXPro 33.6 Vocal ASVD PnP */ | ||
198 | {"LAS4040"}, /* LASAT Internet 33600 PnP */ | ||
199 | {"LAS4540"}, /* Lasat Safire 560 PnP */ | ||
200 | {"LAS5440"}, /* Lasat Safire 336 PnP */ | ||
201 | {"MNP0281"}, /* Microcom TravelPorte FAST V.34 Plug & Play */ | ||
202 | {"MNP0336"}, /* Microcom DeskPorte V.34 FAST or FAST+ Plug & Play */ | ||
203 | {"MNP0339"}, /* Microcom DeskPorte FAST EP 28.8 Plug & Play */ | ||
204 | {"MNP0342"}, /* Microcom DeskPorte 28.8P Plug & Play */ | ||
205 | {"MNP0500"}, /* Microcom DeskPorte FAST ES 28.8 Plug & Play */ | ||
206 | {"MNP0501"}, /* Microcom DeskPorte FAST ES 28.8 Plug & Play */ | ||
207 | {"MNP0502"}, /* Microcom DeskPorte 28.8S Internal Plug & Play */ | ||
208 | {"MOT1105"}, /* Motorola BitSURFR Plug & Play */ | ||
209 | {"MOT1111"}, /* Motorola TA210 Plug & Play */ | ||
210 | {"MOT1114"}, /* Motorola HMTA 200 (ISDN) Plug & Play */ | ||
211 | {"MOT1115"}, /* Motorola BitSURFR Plug & Play */ | ||
212 | {"MOT1190"}, /* Motorola Lifestyle 28.8 Internal */ | ||
213 | {"MOT1501"}, /* Motorola V.3400 Plug & Play */ | ||
214 | {"MOT1502"}, /* Motorola Lifestyle 28.8 V.34 Plug & Play */ | ||
215 | {"MOT1505"}, /* Motorola Power 28.8 V.34 Plug & Play */ | ||
216 | {"MOT1509"}, /* Motorola ModemSURFR External 28.8 Plug & Play */ | ||
217 | {"MOT150A"}, /* Motorola Premier 33.6 Desktop Plug & Play */ | ||
218 | {"MOT150F"}, /* Motorola VoiceSURFR 56K External PnP */ | ||
219 | {"MOT1510"}, /* Motorola ModemSURFR 56K External PnP */ | ||
220 | {"MOT1550"}, /* Motorola ModemSURFR 56K Internal PnP */ | ||
221 | {"MOT1560"}, /* Motorola ModemSURFR Internal 28.8 Plug & Play */ | ||
222 | {"MOT1580"}, /* Motorola Premier 33.6 Internal Plug & Play */ | ||
223 | {"MOT15B0"}, /* Motorola OnlineSURFR 28.8 Internal Plug & Play */ | ||
224 | {"MOT15F0"}, /* Motorola VoiceSURFR 56K Internal PnP */ | ||
225 | {"MVX00A1"}, /* Deskline K56 Phone System PnP */ | ||
226 | {"MVX00F2"}, /* PC Rider K56 Phone System PnP */ | ||
227 | {"nEC8241"}, /* NEC 98NOTE SPEAKER PHONE FAX MODEM(33600bps) */ | ||
228 | {"PMC2430"}, /* Pace 56 Voice Internal Plug & Play Modem */ | ||
229 | {"PNP0500"}, /* Generic standard PC COM port */ | ||
230 | {"PNP0501"}, /* Generic 16550A-compatible COM port */ | ||
231 | {"PNPC000"}, /* Compaq 14400 Modem */ | ||
232 | {"PNPC001"}, /* Compaq 2400/9600 Modem */ | ||
233 | {"PNPC031"}, /* Dial-Up Networking Serial Cable between 2 PCs */ | ||
234 | {"PNPC032"}, /* Dial-Up Networking Parallel Cable between 2 PCs */ | ||
235 | {"PNPC100"}, /* Standard 9600 bps Modem */ | ||
236 | {"PNPC101"}, /* Standard 14400 bps Modem */ | ||
237 | {"PNPC102"}, /* Standard 28800 bps Modem */ | ||
238 | {"PNPC103"}, /* Standard Modem */ | ||
239 | {"PNPC104"}, /* Standard 9600 bps Modem */ | ||
240 | {"PNPC105"}, /* Standard 14400 bps Modem */ | ||
241 | {"PNPC106"}, /* Standard 28800 bps Modem */ | ||
242 | {"PNPC107"}, /* Standard Modem */ | ||
243 | {"PNPC108"}, /* Standard 9600 bps Modem */ | ||
244 | {"PNPC109"}, /* Standard 14400 bps Modem */ | ||
245 | {"PNPC10A"}, /* Standard 28800 bps Modem */ | ||
246 | {"PNPC10B"}, /* Standard Modem */ | ||
247 | {"PNPC10C"}, /* Standard 9600 bps Modem */ | ||
248 | {"PNPC10D"}, /* Standard 14400 bps Modem */ | ||
249 | {"PNPC10E"}, /* Standard 28800 bps Modem */ | ||
250 | {"PNPC10F"}, /* Standard Modem */ | ||
251 | {"PNP2000"}, /* Standard PCMCIA Card Modem */ | ||
252 | {"ROK0030"}, /* Rockwell 33.6 DPF Internal PnP, Modular Technology 33.6 Internal PnP */ | ||
253 | {"ROK0100"}, /* KORTEX 14400 Externe PnP */ | ||
254 | {"ROK4120"}, /* Rockwell 28.8 */ | ||
255 | {"ROK4920"}, /* Viking 28.8 INTERNAL Fax+Data+Voice PnP */ | ||
256 | {"RSS00A0"}, /* Rockwell 33.6 DPF External PnP, BT Prologue 33.6 External PnP, Modular Technology 33.6 External PnP */ | ||
257 | {"RSS0262"}, /* Viking 56K FAX INT */ | ||
258 | {"RSS0250"}, /* K56 par,VV,Voice,Speakphone,AudioSpan,PnP */ | ||
259 | {"SUP1310"}, /* SupraExpress 28.8 Data/Fax PnP modem */ | ||
260 | {"SUP1381"}, /* SupraExpress 336i PnP Voice Modem */ | ||
261 | {"SUP1421"}, /* SupraExpress 33.6 Data/Fax PnP modem */ | ||
262 | {"SUP1590"}, /* SupraExpress 33.6 Data/Fax PnP modem */ | ||
263 | {"SUP1620"}, /* SupraExpress 336i Sp ASVD */ | ||
264 | {"SUP1760"}, /* SupraExpress 33.6 Data/Fax PnP modem */ | ||
265 | {"SUP2171"}, /* SupraExpress 56i Sp Intl */ | ||
266 | {"TEX0011"}, /* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */ | ||
267 | {"UAC000F"}, /* Archtek SmartLink Modem 3334BT Plug & Play */ | ||
268 | {"USR0000"}, /* 3Com Corp. Gateway Telepath IIvi 33.6 */ | ||
269 | {"USR0002"}, /* U.S. Robotics Sporster 33.6K Fax INT PnP */ | ||
270 | {"USR0004"}, /* Sportster Vi 14.4 PnP FAX Voicemail */ | ||
271 | {"USR0006"}, /* U.S. Robotics 33.6K Voice INT PnP */ | ||
272 | {"USR0007"}, /* U.S. Robotics 33.6K Voice EXT PnP */ | ||
273 | {"USR0009"}, /* U.S. Robotics Courier V.Everything INT PnP */ | ||
274 | {"USR2002"}, /* U.S. Robotics 33.6K Voice INT PnP */ | ||
275 | {"USR2070"}, /* U.S. Robotics 56K Voice INT PnP */ | ||
276 | {"USR2080"}, /* U.S. Robotics 56K Voice EXT PnP */ | ||
277 | {"USR3031"}, /* U.S. Robotics 56K FAX INT */ | ||
278 | {"USR3050"}, /* U.S. Robotics 56K FAX INT */ | ||
279 | {"USR3070"}, /* U.S. Robotics 56K Voice INT PnP */ | ||
280 | {"USR3080"}, /* U.S. Robotics 56K Voice EXT PnP */ | ||
281 | {"USR3090"}, /* U.S. Robotics 56K Voice INT PnP */ | ||
282 | {"USR9100"}, /* U.S. Robotics 56K Message */ | ||
283 | {"USR9160"}, /* U.S. Robotics 56K FAX EXT PnP */ | ||
284 | {"USR9170"}, /* U.S. Robotics 56K FAX INT PnP */ | ||
285 | {"USR9180"}, /* U.S. Robotics 56K Voice EXT PnP */ | ||
286 | {"USR9190"}, /* U.S. Robotics 56K Voice INT PnP */ | ||
287 | {"WACFXXX"}, /* Wacom tablets */ | ||
288 | {"FPI2002"}, /* Compaq touchscreen */ | ||
289 | {"FUJ02B2"}, /* Fujitsu Stylistic touchscreens */ | ||
290 | {"FUJ02B3"}, | ||
291 | {"FUJ02B4"}, /* Fujitsu Stylistic LT touchscreens */ | ||
292 | {"FUJ02B6"}, /* Passive Fujitsu Stylistic touchscreens */ | ||
293 | {"FUJ02B7"}, | ||
294 | {"FUJ02B8"}, | ||
295 | {"FUJ02B9"}, | ||
296 | {"FUJ02BC"}, | ||
297 | {"FUJ02E5"}, /* Fujitsu Wacom Tablet PC device */ | ||
298 | {"FUJ02E6"}, /* Fujitsu P-series tablet PC device */ | ||
299 | {"FUJ02E7"}, /* Fujitsu Wacom 2FGT Tablet PC device */ | ||
300 | {"FUJ02E9"}, /* Fujitsu Wacom 1FGT Tablet PC device */ | ||
301 | {"LTS0001"}, /* LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in disguise) */ | ||
302 | {"WCI0003"}, /* Rockwell's (PORALiNK) 33600 INT PNP */ | ||
303 | {"WEC1022"}, /* Winbond CIR port, should not be probed. We should keep track of it to prevent the legacy serial driver from probing it */ | ||
304 | /* scl200wdt */ | ||
305 | {"NSC0800"}, /* National Semiconductor PC87307/PC97307 watchdog component */ | ||
306 | /* mpu401 */ | ||
307 | {"PNPb006"}, | ||
308 | /* cs423x-pnpbios */ | ||
309 | {"CSC0100"}, | ||
310 | {"CSC0000"}, | ||
311 | {"GIM0100"}, /* Guillemot Turtlebeach something appears to be cs4232 compatible */ | ||
312 | /* es18xx-pnpbios */ | ||
313 | {"ESS1869"}, | ||
314 | {"ESS1879"}, | ||
315 | /* snd-opl3sa2-pnpbios */ | ||
316 | {"YMH0021"}, | ||
317 | {"NMX2210"}, /* Gateway Solo 2500 */ | ||
318 | {""}, | ||
319 | }; | ||
320 | |||
321 | static bool is_hex_digit(char c) | ||
322 | { | ||
323 | return (c >= 0 && c <= '9') || (c >= 'A' && c <= 'F'); | ||
324 | } | ||
325 | |||
326 | static bool matching_id(char *idstr, char *list_id) | ||
327 | { | ||
328 | int i; | ||
329 | |||
330 | if (memcmp(idstr, list_id, 3)) | ||
331 | return false; | ||
332 | |||
333 | for (i = 3; i < 7; i++) { | ||
334 | char c = toupper(idstr[i]); | ||
335 | |||
336 | if (!is_hex_digit(c) | ||
337 | || (list_id[i] != 'X' && c != toupper(list_id[i]))) | ||
338 | return false; | ||
339 | } | ||
340 | return true; | ||
341 | } | ||
342 | |||
343 | static bool acpi_pnp_match(char *idstr, const struct acpi_device_id **matchid) | ||
344 | { | ||
345 | const struct acpi_device_id *devid; | ||
346 | |||
347 | for (devid = acpi_pnp_device_ids; devid->id[0]; devid++) | ||
348 | if (matching_id(idstr, (char *)devid->id)) { | ||
349 | if (matchid) | ||
350 | *matchid = devid; | ||
351 | |||
352 | return true; | ||
353 | } | ||
354 | |||
355 | return false; | ||
356 | } | ||
357 | |||
358 | static int acpi_pnp_attach(struct acpi_device *adev, | ||
359 | const struct acpi_device_id *id) | ||
360 | { | ||
361 | return 1; | ||
362 | } | ||
363 | |||
364 | static struct acpi_scan_handler acpi_pnp_handler = { | ||
365 | .ids = acpi_pnp_device_ids, | ||
366 | .match = acpi_pnp_match, | ||
367 | .attach = acpi_pnp_attach, | ||
368 | }; | ||
369 | |||
370 | /* | ||
371 | * For CMOS RTC devices, the PNP ACPI scan handler does not work, because | ||
372 | * there is a CMOS RTC ACPI scan handler installed already, so we need to | ||
373 | * check those devices and enumerate them to the PNP bus directly. | ||
374 | */ | ||
375 | static int is_cmos_rtc_device(struct acpi_device *adev) | ||
376 | { | ||
377 | struct acpi_device_id ids[] = { | ||
378 | { "PNP0B00" }, | ||
379 | { "PNP0B01" }, | ||
380 | { "PNP0B02" }, | ||
381 | {""}, | ||
382 | }; | ||
383 | return !acpi_match_device_ids(adev, ids); | ||
384 | } | ||
385 | |||
386 | bool acpi_is_pnp_device(struct acpi_device *adev) | ||
387 | { | ||
388 | return adev->handler == &acpi_pnp_handler || is_cmos_rtc_device(adev); | ||
389 | } | ||
390 | EXPORT_SYMBOL_GPL(acpi_is_pnp_device); | ||
391 | |||
392 | void __init acpi_pnp_init(void) | ||
393 | { | ||
394 | acpi_scan_add_handler(&acpi_pnp_handler); | ||
395 | } | ||
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 52c81c49cc7d..1c085742644f 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c | |||
@@ -268,7 +268,7 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
268 | pr->apic_id = apic_id; | 268 | pr->apic_id = apic_id; |
269 | 269 | ||
270 | cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); | 270 | cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); |
271 | if (!cpu0_initialized) { | 271 | if (!cpu0_initialized && !acpi_lapic) { |
272 | cpu0_initialized = 1; | 272 | cpu0_initialized = 1; |
273 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ | 273 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ |
274 | if ((cpu_index == -1) && (num_online_cpus() == 1)) | 274 | if ((cpu_index == -1) && (num_online_cpus() == 1)) |
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index b7ed86a20427..8bb43f06e11f 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -135,6 +135,7 @@ acpi-y += \ | |||
135 | rsxface.o | 135 | rsxface.o |
136 | 136 | ||
137 | acpi-y += \ | 137 | acpi-y += \ |
138 | tbdata.o \ | ||
138 | tbfadt.o \ | 139 | tbfadt.o \ |
139 | tbfind.o \ | 140 | tbfind.o \ |
140 | tbinstal.o \ | 141 | tbinstal.o \ |
diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h new file mode 100644 index 000000000000..8698ffba6f39 --- /dev/null +++ b/drivers/acpi/acpica/acapps.h | |||
@@ -0,0 +1,170 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: acapps - common include for ACPI applications/tools | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #ifndef _ACAPPS | ||
45 | #define _ACAPPS | ||
46 | |||
47 | /* Common info for tool signons */ | ||
48 | |||
49 | #define ACPICA_NAME "Intel ACPI Component Architecture" | ||
50 | #define ACPICA_COPYRIGHT "Copyright (c) 2000 - 2014 Intel Corporation" | ||
51 | |||
52 | #if ACPI_MACHINE_WIDTH == 64 | ||
53 | #define ACPI_WIDTH "-64" | ||
54 | |||
55 | #elif ACPI_MACHINE_WIDTH == 32 | ||
56 | #define ACPI_WIDTH "-32" | ||
57 | |||
58 | #else | ||
59 | #error unknown ACPI_MACHINE_WIDTH | ||
60 | #define ACPI_WIDTH "-??" | ||
61 | |||
62 | #endif | ||
63 | |||
64 | /* Macros for signons and file headers */ | ||
65 | |||
66 | #define ACPI_COMMON_SIGNON(utility_name) \ | ||
67 | "\n%s\n%s version %8.8X%s [%s]\n%s\n\n", \ | ||
68 | ACPICA_NAME, \ | ||
69 | utility_name, ((u32) ACPI_CA_VERSION), ACPI_WIDTH, __DATE__, \ | ||
70 | ACPICA_COPYRIGHT | ||
71 | |||
72 | #define ACPI_COMMON_HEADER(utility_name, prefix) \ | ||
73 | "%s%s\n%s%s version %8.8X%s [%s]\n%s%s\n%s\n", \ | ||
74 | prefix, ACPICA_NAME, \ | ||
75 | prefix, utility_name, ((u32) ACPI_CA_VERSION), ACPI_WIDTH, __DATE__, \ | ||
76 | prefix, ACPICA_COPYRIGHT, \ | ||
77 | prefix | ||
78 | |||
79 | /* Macros for usage messages */ | ||
80 | |||
81 | #define ACPI_USAGE_HEADER(usage) \ | ||
82 | printf ("Usage: %s\nOptions:\n", usage); | ||
83 | |||
84 | #define ACPI_OPTION(name, description) \ | ||
85 | printf (" %-18s%s\n", name, description); | ||
86 | |||
87 | #define FILE_SUFFIX_DISASSEMBLY "dsl" | ||
88 | #define ACPI_TABLE_FILE_SUFFIX ".dat" | ||
89 | |||
90 | /* | ||
91 | * getopt | ||
92 | */ | ||
93 | int acpi_getopt(int argc, char **argv, char *opts); | ||
94 | |||
95 | int acpi_getopt_argument(int argc, char **argv); | ||
96 | |||
97 | extern int acpi_gbl_optind; | ||
98 | extern int acpi_gbl_opterr; | ||
99 | extern int acpi_gbl_sub_opt_char; | ||
100 | extern char *acpi_gbl_optarg; | ||
101 | |||
102 | /* | ||
103 | * cmfsize - Common get file size function | ||
104 | */ | ||
105 | u32 cm_get_file_size(FILE * file); | ||
106 | |||
107 | #ifndef ACPI_DUMP_APP | ||
108 | /* | ||
109 | * adisasm | ||
110 | */ | ||
111 | acpi_status | ||
112 | ad_aml_disassemble(u8 out_to_file, | ||
113 | char *filename, char *prefix, char **out_filename); | ||
114 | |||
115 | void ad_print_statistics(void); | ||
116 | |||
117 | acpi_status ad_find_dsdt(u8 **dsdt_ptr, u32 *dsdt_length); | ||
118 | |||
119 | void ad_dump_tables(void); | ||
120 | |||
121 | acpi_status ad_get_local_tables(void); | ||
122 | |||
123 | acpi_status | ||
124 | ad_parse_table(struct acpi_table_header *table, | ||
125 | acpi_owner_id * owner_id, u8 load_table, u8 external); | ||
126 | |||
127 | acpi_status ad_display_tables(char *filename, struct acpi_table_header *table); | ||
128 | |||
129 | acpi_status ad_display_statistics(void); | ||
130 | |||
131 | /* | ||
132 | * adwalk | ||
133 | */ | ||
134 | void | ||
135 | acpi_dm_cross_reference_namespace(union acpi_parse_object *parse_tree_root, | ||
136 | struct acpi_namespace_node *namespace_root, | ||
137 | acpi_owner_id owner_id); | ||
138 | |||
139 | void acpi_dm_dump_tree(union acpi_parse_object *origin); | ||
140 | |||
141 | void acpi_dm_find_orphan_methods(union acpi_parse_object *origin); | ||
142 | |||
143 | void | ||
144 | acpi_dm_finish_namespace_load(union acpi_parse_object *parse_tree_root, | ||
145 | struct acpi_namespace_node *namespace_root, | ||
146 | acpi_owner_id owner_id); | ||
147 | |||
148 | void | ||
149 | acpi_dm_convert_resource_indexes(union acpi_parse_object *parse_tree_root, | ||
150 | struct acpi_namespace_node *namespace_root); | ||
151 | |||
152 | /* | ||
153 | * adfile | ||
154 | */ | ||
155 | acpi_status ad_initialize(void); | ||
156 | |||
157 | char *fl_generate_filename(char *input_filename, char *suffix); | ||
158 | |||
159 | acpi_status | ||
160 | fl_split_input_pathname(char *input_path, | ||
161 | char **out_directory_path, char **out_filename); | ||
162 | |||
163 | char *ad_generate_filename(char *prefix, char *table_id); | ||
164 | |||
165 | void | ||
166 | ad_write_table(struct acpi_table_header *table, | ||
167 | u32 length, char *table_name, char *oem_table_id); | ||
168 | #endif | ||
169 | |||
170 | #endif /* _ACAPPS */ | ||
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 68ec61fff188..7a7811a9fc26 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -104,9 +104,10 @@ acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info); | |||
104 | */ | 104 | */ |
105 | acpi_status | 105 | acpi_status |
106 | acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | 106 | acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, |
107 | struct acpi_generic_address *gpe_block_address, | 107 | u64 address, |
108 | u8 space_id, | ||
108 | u32 register_count, | 109 | u32 register_count, |
109 | u8 gpe_block_base_number, | 110 | u16 gpe_block_base_number, |
110 | u32 interrupt_number, | 111 | u32 interrupt_number, |
111 | struct acpi_gpe_block_info **return_gpe_block); | 112 | struct acpi_gpe_block_info **return_gpe_block); |
112 | 113 | ||
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index a08a448068dd..115eedcade1e 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -44,144 +44,14 @@ | |||
44 | #ifndef __ACGLOBAL_H__ | 44 | #ifndef __ACGLOBAL_H__ |
45 | #define __ACGLOBAL_H__ | 45 | #define __ACGLOBAL_H__ |
46 | 46 | ||
47 | /* | ||
48 | * Ensure that the globals are actually defined and initialized only once. | ||
49 | * | ||
50 | * The use of these macros allows a single list of globals (here) in order | ||
51 | * to simplify maintenance of the code. | ||
52 | */ | ||
53 | #ifdef DEFINE_ACPI_GLOBALS | ||
54 | #define ACPI_GLOBAL(type,name) \ | ||
55 | extern type name; \ | ||
56 | type name | ||
57 | |||
58 | #define ACPI_INIT_GLOBAL(type,name,value) \ | ||
59 | type name=value | ||
60 | |||
61 | #else | ||
62 | #define ACPI_GLOBAL(type,name) \ | ||
63 | extern type name | ||
64 | |||
65 | #define ACPI_INIT_GLOBAL(type,name,value) \ | ||
66 | extern type name | ||
67 | #endif | ||
68 | |||
69 | #ifdef DEFINE_ACPI_GLOBALS | ||
70 | |||
71 | /* Public globals, available from outside ACPICA subsystem */ | ||
72 | |||
73 | /***************************************************************************** | 47 | /***************************************************************************** |
74 | * | 48 | * |
75 | * Runtime configuration (static defaults that can be overriden at runtime) | 49 | * Globals related to the ACPI tables |
76 | * | 50 | * |
77 | ****************************************************************************/ | 51 | ****************************************************************************/ |
78 | 52 | ||
79 | /* | 53 | /* Master list of all ACPI tables that were found in the RSDT/XSDT */ |
80 | * Enable "slack" in the AML interpreter? Default is FALSE, and the | ||
81 | * interpreter strictly follows the ACPI specification. Setting to TRUE | ||
82 | * allows the interpreter to ignore certain errors and/or bad AML constructs. | ||
83 | * | ||
84 | * Currently, these features are enabled by this flag: | ||
85 | * | ||
86 | * 1) Allow "implicit return" of last value in a control method | ||
87 | * 2) Allow access beyond the end of an operation region | ||
88 | * 3) Allow access to uninitialized locals/args (auto-init to integer 0) | ||
89 | * 4) Allow ANY object type to be a source operand for the Store() operator | ||
90 | * 5) Allow unresolved references (invalid target name) in package objects | ||
91 | * 6) Enable warning messages for behavior that is not ACPI spec compliant | ||
92 | */ | ||
93 | ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_interpreter_slack, FALSE); | ||
94 | 54 | ||
95 | /* | ||
96 | * Automatically serialize all methods that create named objects? Default | ||
97 | * is TRUE, meaning that all non_serialized methods are scanned once at | ||
98 | * table load time to determine those that create named objects. Methods | ||
99 | * that create named objects are marked Serialized in order to prevent | ||
100 | * possible run-time problems if they are entered by more than one thread. | ||
101 | */ | ||
102 | ACPI_INIT_GLOBAL(u8, acpi_gbl_auto_serialize_methods, TRUE); | ||
103 | |||
104 | /* | ||
105 | * Create the predefined _OSI method in the namespace? Default is TRUE | ||
106 | * because ACPI CA is fully compatible with other ACPI implementations. | ||
107 | * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior. | ||
108 | */ | ||
109 | ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE); | ||
110 | |||
111 | /* | ||
112 | * Optionally use default values for the ACPI register widths. Set this to | ||
113 | * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. | ||
114 | */ | ||
115 | ACPI_INIT_GLOBAL(u8, acpi_gbl_use_default_register_widths, TRUE); | ||
116 | |||
117 | /* | ||
118 | * Optionally enable output from the AML Debug Object. | ||
119 | */ | ||
120 | ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_aml_debug_object, FALSE); | ||
121 | |||
122 | /* | ||
123 | * Optionally copy the entire DSDT to local memory (instead of simply | ||
124 | * mapping it.) There are some BIOSs that corrupt or replace the original | ||
125 | * DSDT, creating the need for this option. Default is FALSE, do not copy | ||
126 | * the DSDT. | ||
127 | */ | ||
128 | ACPI_INIT_GLOBAL(u8, acpi_gbl_copy_dsdt_locally, FALSE); | ||
129 | |||
130 | /* | ||
131 | * Optionally ignore an XSDT if present and use the RSDT instead. | ||
132 | * Although the ACPI specification requires that an XSDT be used instead | ||
133 | * of the RSDT, the XSDT has been found to be corrupt or ill-formed on | ||
134 | * some machines. Default behavior is to use the XSDT if present. | ||
135 | */ | ||
136 | ACPI_INIT_GLOBAL(u8, acpi_gbl_do_not_use_xsdt, FALSE); | ||
137 | |||
138 | /* | ||
139 | * Optionally use 32-bit FADT addresses if and when there is a conflict | ||
140 | * (address mismatch) between the 32-bit and 64-bit versions of the | ||
141 | * address. Although ACPICA adheres to the ACPI specification which | ||
142 | * requires the use of the corresponding 64-bit address if it is non-zero, | ||
143 | * some machines have been found to have a corrupted non-zero 64-bit | ||
144 | * address. Default is TRUE, favor the 32-bit addresses. | ||
145 | */ | ||
146 | ACPI_INIT_GLOBAL(u8, acpi_gbl_use32_bit_fadt_addresses, TRUE); | ||
147 | |||
148 | /* | ||
149 | * Optionally truncate I/O addresses to 16 bits. Provides compatibility | ||
150 | * with other ACPI implementations. NOTE: During ACPICA initialization, | ||
151 | * this value is set to TRUE if any Windows OSI strings have been | ||
152 | * requested by the BIOS. | ||
153 | */ | ||
154 | ACPI_INIT_GLOBAL(u8, acpi_gbl_truncate_io_addresses, FALSE); | ||
155 | |||
156 | /* | ||
157 | * Disable runtime checking and repair of values returned by control methods. | ||
158 | * Use only if the repair is causing a problem on a particular machine. | ||
159 | */ | ||
160 | ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_auto_repair, FALSE); | ||
161 | |||
162 | /* | ||
163 | * Optionally do not load any SSDTs from the RSDT/XSDT during initialization. | ||
164 | * This can be useful for debugging ACPI problems on some machines. | ||
165 | */ | ||
166 | ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_ssdt_table_load, FALSE); | ||
167 | |||
168 | /* | ||
169 | * We keep track of the latest version of Windows that has been requested by | ||
170 | * the BIOS. | ||
171 | */ | ||
172 | ACPI_INIT_GLOBAL(u8, acpi_gbl_osi_data, 0); | ||
173 | |||
174 | #endif /* DEFINE_ACPI_GLOBALS */ | ||
175 | |||
176 | /***************************************************************************** | ||
177 | * | ||
178 | * ACPI Table globals | ||
179 | * | ||
180 | ****************************************************************************/ | ||
181 | |||
182 | /* | ||
183 | * Master list of all ACPI tables that were found in the RSDT/XSDT. | ||
184 | */ | ||
185 | ACPI_GLOBAL(struct acpi_table_list, acpi_gbl_root_table_list); | 55 | ACPI_GLOBAL(struct acpi_table_list, acpi_gbl_root_table_list); |
186 | 56 | ||
187 | /* DSDT information. Used to check for DSDT corruption */ | 57 | /* DSDT information. Used to check for DSDT corruption */ |
@@ -279,7 +149,6 @@ ACPI_GLOBAL(acpi_exception_handler, acpi_gbl_exception_handler); | |||
279 | ACPI_GLOBAL(acpi_init_handler, acpi_gbl_init_handler); | 149 | ACPI_GLOBAL(acpi_init_handler, acpi_gbl_init_handler); |
280 | ACPI_GLOBAL(acpi_table_handler, acpi_gbl_table_handler); | 150 | ACPI_GLOBAL(acpi_table_handler, acpi_gbl_table_handler); |
281 | ACPI_GLOBAL(void *, acpi_gbl_table_handler_context); | 151 | ACPI_GLOBAL(void *, acpi_gbl_table_handler_context); |
282 | ACPI_GLOBAL(struct acpi_walk_state *, acpi_gbl_breakpoint_walk); | ||
283 | ACPI_GLOBAL(acpi_interface_handler, acpi_gbl_interface_handler); | 152 | ACPI_GLOBAL(acpi_interface_handler, acpi_gbl_interface_handler); |
284 | ACPI_GLOBAL(struct acpi_sci_handler_info *, acpi_gbl_sci_handler_list); | 153 | ACPI_GLOBAL(struct acpi_sci_handler_info *, acpi_gbl_sci_handler_list); |
285 | 154 | ||
@@ -296,7 +165,6 @@ ACPI_GLOBAL(u8, acpi_gbl_reg_methods_executed); | |||
296 | /* Misc */ | 165 | /* Misc */ |
297 | 166 | ||
298 | ACPI_GLOBAL(u32, acpi_gbl_original_mode); | 167 | ACPI_GLOBAL(u32, acpi_gbl_original_mode); |
299 | ACPI_GLOBAL(u32, acpi_gbl_rsdp_original_location); | ||
300 | ACPI_GLOBAL(u32, acpi_gbl_ns_lookup_count); | 168 | ACPI_GLOBAL(u32, acpi_gbl_ns_lookup_count); |
301 | ACPI_GLOBAL(u32, acpi_gbl_ps_find_count); | 169 | ACPI_GLOBAL(u32, acpi_gbl_ps_find_count); |
302 | ACPI_GLOBAL(u16, acpi_gbl_pm1_enable_register_save); | 170 | ACPI_GLOBAL(u16, acpi_gbl_pm1_enable_register_save); |
@@ -483,11 +351,6 @@ ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc); | |||
483 | ACPI_GLOBAL(u32, acpi_gbl_num_nodes); | 351 | ACPI_GLOBAL(u32, acpi_gbl_num_nodes); |
484 | ACPI_GLOBAL(u32, acpi_gbl_num_objects); | 352 | ACPI_GLOBAL(u32, acpi_gbl_num_objects); |
485 | 353 | ||
486 | ACPI_GLOBAL(u32, acpi_gbl_size_of_parse_tree); | ||
487 | ACPI_GLOBAL(u32, acpi_gbl_size_of_method_trees); | ||
488 | ACPI_GLOBAL(u32, acpi_gbl_size_of_node_entries); | ||
489 | ACPI_GLOBAL(u32, acpi_gbl_size_of_acpi_objects); | ||
490 | |||
491 | #endif /* ACPI_DEBUGGER */ | 354 | #endif /* ACPI_DEBUGGER */ |
492 | 355 | ||
493 | /***************************************************************************** | 356 | /***************************************************************************** |
@@ -509,5 +372,6 @@ ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL); | |||
509 | ****************************************************************************/ | 372 | ****************************************************************************/ |
510 | 373 | ||
511 | extern const struct ah_predefined_name asl_predefined_info[]; | 374 | extern const struct ah_predefined_name asl_predefined_info[]; |
375 | extern const struct ah_device_id asl_device_ids[]; | ||
512 | 376 | ||
513 | #endif /* __ACGLOBAL_H__ */ | 377 | #endif /* __ACGLOBAL_H__ */ |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 52a21dafb540..91f801a2e689 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -450,9 +450,9 @@ struct acpi_gpe_event_info { | |||
450 | struct acpi_gpe_register_info { | 450 | struct acpi_gpe_register_info { |
451 | struct acpi_generic_address status_address; /* Address of status reg */ | 451 | struct acpi_generic_address status_address; /* Address of status reg */ |
452 | struct acpi_generic_address enable_address; /* Address of enable reg */ | 452 | struct acpi_generic_address enable_address; /* Address of enable reg */ |
453 | u16 base_gpe_number; /* Base GPE number for this register */ | ||
453 | u8 enable_for_wake; /* GPEs to keep enabled when sleeping */ | 454 | u8 enable_for_wake; /* GPEs to keep enabled when sleeping */ |
454 | u8 enable_for_run; /* GPEs to keep enabled when running */ | 455 | u8 enable_for_run; /* GPEs to keep enabled when running */ |
455 | u8 base_gpe_number; /* Base GPE number for this register */ | ||
456 | }; | 456 | }; |
457 | 457 | ||
458 | /* | 458 | /* |
@@ -466,11 +466,12 @@ struct acpi_gpe_block_info { | |||
466 | struct acpi_gpe_xrupt_info *xrupt_block; /* Backpointer to interrupt block */ | 466 | struct acpi_gpe_xrupt_info *xrupt_block; /* Backpointer to interrupt block */ |
467 | struct acpi_gpe_register_info *register_info; /* One per GPE register pair */ | 467 | struct acpi_gpe_register_info *register_info; /* One per GPE register pair */ |
468 | struct acpi_gpe_event_info *event_info; /* One for each GPE */ | 468 | struct acpi_gpe_event_info *event_info; /* One for each GPE */ |
469 | struct acpi_generic_address block_address; /* Base address of the block */ | 469 | u64 address; /* Base address of the block */ |
470 | u32 register_count; /* Number of register pairs in block */ | 470 | u32 register_count; /* Number of register pairs in block */ |
471 | u16 gpe_count; /* Number of individual GPEs in block */ | 471 | u16 gpe_count; /* Number of individual GPEs in block */ |
472 | u8 block_base_number; /* Base GPE number for this block */ | 472 | u16 block_base_number; /* Base GPE number for this block */ |
473 | u8 initialized; /* TRUE if this block is initialized */ | 473 | u8 space_id; |
474 | u8 initialized; /* TRUE if this block is initialized */ | ||
474 | }; | 475 | }; |
475 | 476 | ||
476 | /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ | 477 | /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ |
@@ -733,7 +734,8 @@ union acpi_parse_value { | |||
733 | #define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */ | 734 | #define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */ |
734 | #define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */ | 735 | #define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */ |
735 | #define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */ | 736 | #define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */ |
736 | #define ACPI_DASM_IGNORE 0x09 /* Not used at this time */ | 737 | #define ACPI_DASM_HID_STRING 0x09 /* String is a _HID or _CID */ |
738 | #define ACPI_DASM_IGNORE 0x0A /* Not used at this time */ | ||
737 | 739 | ||
738 | /* | 740 | /* |
739 | * Generic operation (for example: If, While, Store) | 741 | * Generic operation (for example: If, While, Store) |
@@ -1147,4 +1149,9 @@ struct ah_predefined_name { | |||
1147 | #endif | 1149 | #endif |
1148 | }; | 1150 | }; |
1149 | 1151 | ||
1152 | struct ah_device_id { | ||
1153 | char *name; | ||
1154 | char *description; | ||
1155 | }; | ||
1156 | |||
1150 | #endif /* __ACLOCAL_H__ */ | 1157 | #endif /* __ACLOCAL_H__ */ |
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index a48d713e9599..bd08817cafd8 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h | |||
@@ -586,6 +586,10 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { | |||
586 | {{"_LID", METHOD_0ARGS, | 586 | {{"_LID", METHOD_0ARGS, |
587 | METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, | 587 | METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, |
588 | 588 | ||
589 | {{"_LPD", METHOD_0ARGS, | ||
590 | METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (1 Int(rev), n Pkg (2 Int) */ | ||
591 | PACKAGE_INFO(ACPI_PTYPE2_REV_FIXED, ACPI_RTYPE_INTEGER, 2, 0, 0, 0), | ||
592 | |||
589 | {{"_MAT", METHOD_0ARGS, | 593 | {{"_MAT", METHOD_0ARGS, |
590 | METHOD_RETURNS(ACPI_RTYPE_BUFFER)}}, | 594 | METHOD_RETURNS(ACPI_RTYPE_BUFFER)}}, |
591 | 595 | ||
@@ -698,12 +702,6 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { | |||
698 | METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */ | 702 | METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */ |
699 | PACKAGE_INFO(ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0), | 703 | PACKAGE_INFO(ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0), |
700 | 704 | ||
701 | {{"_PRP", METHOD_0ARGS, | ||
702 | METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each: 1 Str, 1 Int/Str/Pkg */ | ||
703 | PACKAGE_INFO(ACPI_PTYPE2, ACPI_RTYPE_STRING, 1, | ||
704 | ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | | ||
705 | ACPI_RTYPE_PACKAGE | ACPI_RTYPE_REFERENCE, 1, 0), | ||
706 | |||
707 | {{"_PRS", METHOD_0ARGS, | 705 | {{"_PRS", METHOD_0ARGS, |
708 | METHOD_RETURNS(ACPI_RTYPE_BUFFER)}}, | 706 | METHOD_RETURNS(ACPI_RTYPE_BUFFER)}}, |
709 | 707 | ||
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 5fa4b2027697..f14882788eee 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h | |||
@@ -54,6 +54,31 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); | |||
54 | u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length); | 54 | u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length); |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * tbdata - table data structure management | ||
58 | */ | ||
59 | acpi_status acpi_tb_get_next_root_index(u32 *table_index); | ||
60 | |||
61 | void | ||
62 | acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc, | ||
63 | acpi_physical_address address, | ||
64 | u8 flags, struct acpi_table_header *table); | ||
65 | |||
66 | acpi_status | ||
67 | acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc, | ||
68 | acpi_physical_address address, u8 flags); | ||
69 | |||
70 | void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc); | ||
71 | |||
72 | acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc); | ||
73 | |||
74 | acpi_status | ||
75 | acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature); | ||
76 | |||
77 | u8 acpi_tb_is_table_loaded(u32 table_index); | ||
78 | |||
79 | void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded); | ||
80 | |||
81 | /* | ||
57 | * tbfadt - FADT parse/convert/validate | 82 | * tbfadt - FADT parse/convert/validate |
58 | */ | 83 | */ |
59 | void acpi_tb_parse_fadt(u32 table_index); | 84 | void acpi_tb_parse_fadt(u32 table_index); |
@@ -72,22 +97,32 @@ acpi_tb_find_table(char *signature, | |||
72 | */ | 97 | */ |
73 | acpi_status acpi_tb_resize_root_table_list(void); | 98 | acpi_status acpi_tb_resize_root_table_list(void); |
74 | 99 | ||
75 | acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc); | 100 | acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc); |
101 | |||
102 | void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc); | ||
103 | |||
104 | void acpi_tb_override_table(struct acpi_table_desc *old_table_desc); | ||
76 | 105 | ||
77 | struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header | 106 | acpi_status |
78 | *table_header, | 107 | acpi_tb_acquire_table(struct acpi_table_desc *table_desc, |
79 | struct acpi_table_desc | 108 | struct acpi_table_header **table_ptr, |
80 | *table_desc); | 109 | u32 *table_length, u8 *table_flags); |
110 | |||
111 | void | ||
112 | acpi_tb_release_table(struct acpi_table_header *table, | ||
113 | u32 table_length, u8 table_flags); | ||
81 | 114 | ||
82 | acpi_status | 115 | acpi_status |
83 | acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index); | 116 | acpi_tb_install_standard_table(acpi_physical_address address, |
117 | u8 flags, | ||
118 | u8 reload, u8 override, u32 *table_index); | ||
84 | 119 | ||
85 | acpi_status | 120 | acpi_status |
86 | acpi_tb_store_table(acpi_physical_address address, | 121 | acpi_tb_store_table(acpi_physical_address address, |
87 | struct acpi_table_header *table, | 122 | struct acpi_table_header *table, |
88 | u32 length, u8 flags, u32 *table_index); | 123 | u32 length, u8 flags, u32 *table_index); |
89 | 124 | ||
90 | void acpi_tb_delete_table(struct acpi_table_desc *table_desc); | 125 | void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc); |
91 | 126 | ||
92 | void acpi_tb_terminate(void); | 127 | void acpi_tb_terminate(void); |
93 | 128 | ||
@@ -99,10 +134,6 @@ acpi_status acpi_tb_release_owner_id(u32 table_index); | |||
99 | 134 | ||
100 | acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id); | 135 | acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id); |
101 | 136 | ||
102 | u8 acpi_tb_is_table_loaded(u32 table_index); | ||
103 | |||
104 | void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded); | ||
105 | |||
106 | /* | 137 | /* |
107 | * tbutils - table manager utilities | 138 | * tbutils - table manager utilities |
108 | */ | 139 | */ |
@@ -124,8 +155,13 @@ void acpi_tb_check_dsdt_header(void); | |||
124 | struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index); | 155 | struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index); |
125 | 156 | ||
126 | void | 157 | void |
127 | acpi_tb_install_table(acpi_physical_address address, | 158 | acpi_tb_install_table_with_override(u32 table_index, |
128 | char *signature, u32 table_index); | 159 | struct acpi_table_desc *new_table_desc, |
160 | u8 override); | ||
161 | |||
162 | acpi_status | ||
163 | acpi_tb_install_fixed_table(acpi_physical_address address, | ||
164 | char *signature, u32 table_index); | ||
129 | 165 | ||
130 | acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address); | 166 | acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address); |
131 | 167 | ||
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index ceeec0b7ccb1..1e256c5bda20 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -176,8 +176,7 @@ acpi_status acpi_ut_init_globals(void); | |||
176 | 176 | ||
177 | char *acpi_ut_get_mutex_name(u32 mutex_id); | 177 | char *acpi_ut_get_mutex_name(u32 mutex_id); |
178 | 178 | ||
179 | const char *acpi_ut_get_notify_name(u32 notify_value); | 179 | const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type); |
180 | |||
181 | #endif | 180 | #endif |
182 | 181 | ||
183 | char *acpi_ut_get_type_name(acpi_object_type type); | 182 | char *acpi_ut_get_type_name(acpi_object_type type); |
@@ -737,4 +736,11 @@ acpi_ut_method_error(const char *module_name, | |||
737 | struct acpi_namespace_node *node, | 736 | struct acpi_namespace_node *node, |
738 | const char *path, acpi_status lookup_status); | 737 | const char *path, acpi_status lookup_status); |
739 | 738 | ||
739 | /* | ||
740 | * Utility functions for ACPI names and IDs | ||
741 | */ | ||
742 | const struct ah_predefined_name *acpi_ah_match_predefined_name(char *nameseg); | ||
743 | |||
744 | const struct ah_device_id *acpi_ah_match_hardware_id(char *hid); | ||
745 | |||
740 | #endif /* _ACUTILS_H */ | 746 | #endif /* _ACUTILS_H */ |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 955f83da68a5..48f70013b488 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -383,7 +383,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
383 | if (!(gpe_register_info->enable_for_run | | 383 | if (!(gpe_register_info->enable_for_run | |
384 | gpe_register_info->enable_for_wake)) { | 384 | gpe_register_info->enable_for_wake)) { |
385 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, | 385 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, |
386 | "Ignore disabled registers for GPE%02X-GPE%02X: " | 386 | "Ignore disabled registers for GPE %02X-%02X: " |
387 | "RunEnable=%02X, WakeEnable=%02X\n", | 387 | "RunEnable=%02X, WakeEnable=%02X\n", |
388 | gpe_register_info-> | 388 | gpe_register_info-> |
389 | base_gpe_number, | 389 | base_gpe_number, |
@@ -416,7 +416,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
416 | } | 416 | } |
417 | 417 | ||
418 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, | 418 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, |
419 | "Read registers for GPE%02X-GPE%02X: Status=%02X, Enable=%02X, " | 419 | "Read registers for GPE %02X-%02X: Status=%02X, Enable=%02X, " |
420 | "RunEnable=%02X, WakeEnable=%02X\n", | 420 | "RunEnable=%02X, WakeEnable=%02X\n", |
421 | gpe_register_info->base_gpe_number, | 421 | gpe_register_info->base_gpe_number, |
422 | gpe_register_info->base_gpe_number + | 422 | gpe_register_info->base_gpe_number + |
@@ -706,7 +706,8 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, | |||
706 | status = acpi_hw_clear_gpe(gpe_event_info); | 706 | status = acpi_hw_clear_gpe(gpe_event_info); |
707 | if (ACPI_FAILURE(status)) { | 707 | if (ACPI_FAILURE(status)) { |
708 | ACPI_EXCEPTION((AE_INFO, status, | 708 | ACPI_EXCEPTION((AE_INFO, status, |
709 | "Unable to clear GPE%02X", gpe_number)); | 709 | "Unable to clear GPE %02X", |
710 | gpe_number)); | ||
710 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); | 711 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); |
711 | } | 712 | } |
712 | } | 713 | } |
@@ -723,7 +724,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, | |||
723 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); | 724 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); |
724 | if (ACPI_FAILURE(status)) { | 725 | if (ACPI_FAILURE(status)) { |
725 | ACPI_EXCEPTION((AE_INFO, status, | 726 | ACPI_EXCEPTION((AE_INFO, status, |
726 | "Unable to disable GPE%02X", gpe_number)); | 727 | "Unable to disable GPE %02X", gpe_number)); |
727 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); | 728 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); |
728 | } | 729 | } |
729 | 730 | ||
@@ -764,7 +765,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, | |||
764 | gpe_event_info); | 765 | gpe_event_info); |
765 | if (ACPI_FAILURE(status)) { | 766 | if (ACPI_FAILURE(status)) { |
766 | ACPI_EXCEPTION((AE_INFO, status, | 767 | ACPI_EXCEPTION((AE_INFO, status, |
767 | "Unable to queue handler for GPE%02X - event disabled", | 768 | "Unable to queue handler for GPE %02X - event disabled", |
768 | gpe_number)); | 769 | gpe_number)); |
769 | } | 770 | } |
770 | break; | 771 | break; |
@@ -776,7 +777,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, | |||
776 | * a GPE to be enabled if it has no handler or method. | 777 | * a GPE to be enabled if it has no handler or method. |
777 | */ | 778 | */ |
778 | ACPI_ERROR((AE_INFO, | 779 | ACPI_ERROR((AE_INFO, |
779 | "No handler or method for GPE%02X, disabling event", | 780 | "No handler or method for GPE %02X, disabling event", |
780 | gpe_number)); | 781 | gpe_number)); |
781 | 782 | ||
782 | break; | 783 | break; |
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index caaed3c673fd..d86699eea33c 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -252,21 +252,17 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) | |||
252 | 252 | ||
253 | /* Init the register_info for this GPE register (8 GPEs) */ | 253 | /* Init the register_info for this GPE register (8 GPEs) */ |
254 | 254 | ||
255 | this_register->base_gpe_number = | 255 | this_register->base_gpe_number = (u16) |
256 | (u8) (gpe_block->block_base_number + | 256 | (gpe_block->block_base_number + |
257 | (i * ACPI_GPE_REGISTER_WIDTH)); | 257 | (i * ACPI_GPE_REGISTER_WIDTH)); |
258 | 258 | ||
259 | this_register->status_address.address = | 259 | this_register->status_address.address = gpe_block->address + i; |
260 | gpe_block->block_address.address + i; | ||
261 | 260 | ||
262 | this_register->enable_address.address = | 261 | this_register->enable_address.address = |
263 | gpe_block->block_address.address + i + | 262 | gpe_block->address + i + gpe_block->register_count; |
264 | gpe_block->register_count; | ||
265 | 263 | ||
266 | this_register->status_address.space_id = | 264 | this_register->status_address.space_id = gpe_block->space_id; |
267 | gpe_block->block_address.space_id; | 265 | this_register->enable_address.space_id = gpe_block->space_id; |
268 | this_register->enable_address.space_id = | ||
269 | gpe_block->block_address.space_id; | ||
270 | this_register->status_address.bit_width = | 266 | this_register->status_address.bit_width = |
271 | ACPI_GPE_REGISTER_WIDTH; | 267 | ACPI_GPE_REGISTER_WIDTH; |
272 | this_register->enable_address.bit_width = | 268 | this_register->enable_address.bit_width = |
@@ -334,9 +330,10 @@ error_exit: | |||
334 | 330 | ||
335 | acpi_status | 331 | acpi_status |
336 | acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | 332 | acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, |
337 | struct acpi_generic_address *gpe_block_address, | 333 | u64 address, |
334 | u8 space_id, | ||
338 | u32 register_count, | 335 | u32 register_count, |
339 | u8 gpe_block_base_number, | 336 | u16 gpe_block_base_number, |
340 | u32 interrupt_number, | 337 | u32 interrupt_number, |
341 | struct acpi_gpe_block_info **return_gpe_block) | 338 | struct acpi_gpe_block_info **return_gpe_block) |
342 | { | 339 | { |
@@ -359,15 +356,14 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
359 | 356 | ||
360 | /* Initialize the new GPE block */ | 357 | /* Initialize the new GPE block */ |
361 | 358 | ||
359 | gpe_block->address = address; | ||
360 | gpe_block->space_id = space_id; | ||
362 | gpe_block->node = gpe_device; | 361 | gpe_block->node = gpe_device; |
363 | gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); | 362 | gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); |
364 | gpe_block->initialized = FALSE; | 363 | gpe_block->initialized = FALSE; |
365 | gpe_block->register_count = register_count; | 364 | gpe_block->register_count = register_count; |
366 | gpe_block->block_base_number = gpe_block_base_number; | 365 | gpe_block->block_base_number = gpe_block_base_number; |
367 | 366 | ||
368 | ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, | ||
369 | sizeof(struct acpi_generic_address)); | ||
370 | |||
371 | /* | 367 | /* |
372 | * Create the register_info and event_info sub-structures | 368 | * Create the register_info and event_info sub-structures |
373 | * Note: disables and clears all GPEs in the block | 369 | * Note: disables and clears all GPEs in the block |
@@ -408,12 +404,14 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
408 | } | 404 | } |
409 | 405 | ||
410 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | 406 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
411 | " Initialized GPE %02X to %02X [%4.4s] %u regs on interrupt 0x%X\n", | 407 | " Initialized GPE %02X to %02X [%4.4s] %u regs on interrupt 0x%X%s\n", |
412 | (u32)gpe_block->block_base_number, | 408 | (u32)gpe_block->block_base_number, |
413 | (u32)(gpe_block->block_base_number + | 409 | (u32)(gpe_block->block_base_number + |
414 | (gpe_block->gpe_count - 1)), | 410 | (gpe_block->gpe_count - 1)), |
415 | gpe_device->name.ascii, gpe_block->register_count, | 411 | gpe_device->name.ascii, gpe_block->register_count, |
416 | interrupt_number)); | 412 | interrupt_number, |
413 | interrupt_number == | ||
414 | acpi_gbl_FADT.sci_interrupt ? " (SCI)" : "")); | ||
417 | 415 | ||
418 | /* Update global count of currently available GPEs */ | 416 | /* Update global count of currently available GPEs */ |
419 | 417 | ||
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index ae779c1e871d..49fc7effd961 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c | |||
@@ -131,8 +131,10 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
131 | /* Install GPE Block 0 */ | 131 | /* Install GPE Block 0 */ |
132 | 132 | ||
133 | status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, | 133 | status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, |
134 | &acpi_gbl_FADT.xgpe0_block, | 134 | acpi_gbl_FADT.xgpe0_block. |
135 | register_count0, 0, | 135 | address, |
136 | acpi_gbl_FADT.xgpe0_block. | ||
137 | space_id, register_count0, 0, | ||
136 | acpi_gbl_FADT.sci_interrupt, | 138 | acpi_gbl_FADT.sci_interrupt, |
137 | &acpi_gbl_gpe_fadt_blocks[0]); | 139 | &acpi_gbl_gpe_fadt_blocks[0]); |
138 | 140 | ||
@@ -169,8 +171,10 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
169 | 171 | ||
170 | status = | 172 | status = |
171 | acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, | 173 | acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, |
172 | &acpi_gbl_FADT.xgpe1_block, | 174 | acpi_gbl_FADT.xgpe1_block. |
173 | register_count1, | 175 | address, |
176 | acpi_gbl_FADT.xgpe1_block. | ||
177 | space_id, register_count1, | ||
174 | acpi_gbl_FADT.gpe1_base, | 178 | acpi_gbl_FADT.gpe1_base, |
175 | acpi_gbl_FADT. | 179 | acpi_gbl_FADT. |
176 | sci_interrupt, | 180 | sci_interrupt, |
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index 5d594eb2e5ec..24ea3424981b 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -167,7 +167,8 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
167 | "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", | 167 | "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", |
168 | acpi_ut_get_node_name(node), | 168 | acpi_ut_get_node_name(node), |
169 | acpi_ut_get_type_name(node->type), notify_value, | 169 | acpi_ut_get_type_name(node->type), notify_value, |
170 | acpi_ut_get_notify_name(notify_value), node)); | 170 | acpi_ut_get_notify_name(notify_value, ACPI_TYPE_ANY), |
171 | node)); | ||
171 | 172 | ||
172 | status = acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch, | 173 | status = acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch, |
173 | info); | 174 | info); |
diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index 4d8a709c1fc4..29630e303829 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c | |||
@@ -117,7 +117,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context) | |||
117 | ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler); | 117 | ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler); |
118 | 118 | ||
119 | /* | 119 | /* |
120 | * We are guaranteed by the ACPI CA initialization/shutdown code that | 120 | * We are guaranteed by the ACPICA initialization/shutdown code that |
121 | * if this interrupt handler is installed, ACPI is enabled. | 121 | * if this interrupt handler is installed, ACPI is enabled. |
122 | */ | 122 | */ |
123 | 123 | ||
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index a734b27da061..11e5803b8b41 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
@@ -239,7 +239,7 @@ acpi_remove_notify_handler(acpi_handle device, | |||
239 | union acpi_operand_object *obj_desc; | 239 | union acpi_operand_object *obj_desc; |
240 | union acpi_operand_object *handler_obj; | 240 | union acpi_operand_object *handler_obj; |
241 | union acpi_operand_object *previous_handler_obj; | 241 | union acpi_operand_object *previous_handler_obj; |
242 | acpi_status status; | 242 | acpi_status status = AE_OK; |
243 | u32 i; | 243 | u32 i; |
244 | 244 | ||
245 | ACPI_FUNCTION_TRACE(acpi_remove_notify_handler); | 245 | ACPI_FUNCTION_TRACE(acpi_remove_notify_handler); |
@@ -251,20 +251,17 @@ acpi_remove_notify_handler(acpi_handle device, | |||
251 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 251 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
252 | } | 252 | } |
253 | 253 | ||
254 | /* Make sure all deferred notify tasks are completed */ | ||
255 | |||
256 | acpi_os_wait_events_complete(); | ||
257 | |||
258 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
259 | if (ACPI_FAILURE(status)) { | ||
260 | return_ACPI_STATUS(status); | ||
261 | } | ||
262 | |||
263 | /* Root Object. Global handlers are removed here */ | 254 | /* Root Object. Global handlers are removed here */ |
264 | 255 | ||
265 | if (device == ACPI_ROOT_OBJECT) { | 256 | if (device == ACPI_ROOT_OBJECT) { |
266 | for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { | 257 | for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { |
267 | if (handler_type & (i + 1)) { | 258 | if (handler_type & (i + 1)) { |
259 | status = | ||
260 | acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
261 | if (ACPI_FAILURE(status)) { | ||
262 | return_ACPI_STATUS(status); | ||
263 | } | ||
264 | |||
268 | if (!acpi_gbl_global_notify[i].handler || | 265 | if (!acpi_gbl_global_notify[i].handler || |
269 | (acpi_gbl_global_notify[i].handler != | 266 | (acpi_gbl_global_notify[i].handler != |
270 | handler)) { | 267 | handler)) { |
@@ -277,31 +274,40 @@ acpi_remove_notify_handler(acpi_handle device, | |||
277 | 274 | ||
278 | acpi_gbl_global_notify[i].handler = NULL; | 275 | acpi_gbl_global_notify[i].handler = NULL; |
279 | acpi_gbl_global_notify[i].context = NULL; | 276 | acpi_gbl_global_notify[i].context = NULL; |
277 | |||
278 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
279 | |||
280 | /* Make sure all deferred notify tasks are completed */ | ||
281 | |||
282 | acpi_os_wait_events_complete(); | ||
280 | } | 283 | } |
281 | } | 284 | } |
282 | 285 | ||
283 | goto unlock_and_exit; | 286 | return_ACPI_STATUS(AE_OK); |
284 | } | 287 | } |
285 | 288 | ||
286 | /* All other objects: Are Notifies allowed on this object? */ | 289 | /* All other objects: Are Notifies allowed on this object? */ |
287 | 290 | ||
288 | if (!acpi_ev_is_notify_object(node)) { | 291 | if (!acpi_ev_is_notify_object(node)) { |
289 | status = AE_TYPE; | 292 | return_ACPI_STATUS(AE_TYPE); |
290 | goto unlock_and_exit; | ||
291 | } | 293 | } |
292 | 294 | ||
293 | /* Must have an existing internal object */ | 295 | /* Must have an existing internal object */ |
294 | 296 | ||
295 | obj_desc = acpi_ns_get_attached_object(node); | 297 | obj_desc = acpi_ns_get_attached_object(node); |
296 | if (!obj_desc) { | 298 | if (!obj_desc) { |
297 | status = AE_NOT_EXIST; | 299 | return_ACPI_STATUS(AE_NOT_EXIST); |
298 | goto unlock_and_exit; | ||
299 | } | 300 | } |
300 | 301 | ||
301 | /* Internal object exists. Find the handler and remove it */ | 302 | /* Internal object exists. Find the handler and remove it */ |
302 | 303 | ||
303 | for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { | 304 | for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { |
304 | if (handler_type & (i + 1)) { | 305 | if (handler_type & (i + 1)) { |
306 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
307 | if (ACPI_FAILURE(status)) { | ||
308 | return_ACPI_STATUS(status); | ||
309 | } | ||
310 | |||
305 | handler_obj = obj_desc->common_notify.notify_list[i]; | 311 | handler_obj = obj_desc->common_notify.notify_list[i]; |
306 | previous_handler_obj = NULL; | 312 | previous_handler_obj = NULL; |
307 | 313 | ||
@@ -329,10 +335,17 @@ acpi_remove_notify_handler(acpi_handle device, | |||
329 | handler_obj->notify.next[i]; | 335 | handler_obj->notify.next[i]; |
330 | } | 336 | } |
331 | 337 | ||
338 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
339 | |||
340 | /* Make sure all deferred notify tasks are completed */ | ||
341 | |||
342 | acpi_os_wait_events_complete(); | ||
332 | acpi_ut_remove_reference(handler_obj); | 343 | acpi_ut_remove_reference(handler_obj); |
333 | } | 344 | } |
334 | } | 345 | } |
335 | 346 | ||
347 | return_ACPI_STATUS(status); | ||
348 | |||
336 | unlock_and_exit: | 349 | unlock_and_exit: |
337 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 350 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
338 | return_ACPI_STATUS(status); | 351 | return_ACPI_STATUS(status); |
@@ -457,6 +470,8 @@ exit: | |||
457 | return_ACPI_STATUS(status); | 470 | return_ACPI_STATUS(status); |
458 | } | 471 | } |
459 | 472 | ||
473 | ACPI_EXPORT_SYMBOL(acpi_install_sci_handler) | ||
474 | |||
460 | /******************************************************************************* | 475 | /******************************************************************************* |
461 | * | 476 | * |
462 | * FUNCTION: acpi_remove_sci_handler | 477 | * FUNCTION: acpi_remove_sci_handler |
@@ -468,7 +483,6 @@ exit: | |||
468 | * DESCRIPTION: Remove a handler for a System Control Interrupt. | 483 | * DESCRIPTION: Remove a handler for a System Control Interrupt. |
469 | * | 484 | * |
470 | ******************************************************************************/ | 485 | ******************************************************************************/ |
471 | |||
472 | acpi_status acpi_remove_sci_handler(acpi_sci_handler address) | 486 | acpi_status acpi_remove_sci_handler(acpi_sci_handler address) |
473 | { | 487 | { |
474 | struct acpi_sci_handler_info *prev_sci_handler; | 488 | struct acpi_sci_handler_info *prev_sci_handler; |
@@ -522,6 +536,8 @@ unlock_and_exit: | |||
522 | return_ACPI_STATUS(status); | 536 | return_ACPI_STATUS(status); |
523 | } | 537 | } |
524 | 538 | ||
539 | ACPI_EXPORT_SYMBOL(acpi_remove_sci_handler) | ||
540 | |||
525 | /******************************************************************************* | 541 | /******************************************************************************* |
526 | * | 542 | * |
527 | * FUNCTION: acpi_install_global_event_handler | 543 | * FUNCTION: acpi_install_global_event_handler |
@@ -537,7 +553,6 @@ unlock_and_exit: | |||
537 | * Can be used to update event counters, etc. | 553 | * Can be used to update event counters, etc. |
538 | * | 554 | * |
539 | ******************************************************************************/ | 555 | ******************************************************************************/ |
540 | |||
541 | acpi_status | 556 | acpi_status |
542 | acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context) | 557 | acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context) |
543 | { | 558 | { |
@@ -840,10 +855,6 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
840 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 855 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
841 | } | 856 | } |
842 | 857 | ||
843 | /* Make sure all deferred GPE tasks are completed */ | ||
844 | |||
845 | acpi_os_wait_events_complete(); | ||
846 | |||
847 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | 858 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); |
848 | if (ACPI_FAILURE(status)) { | 859 | if (ACPI_FAILURE(status)) { |
849 | return_ACPI_STATUS(status); | 860 | return_ACPI_STATUS(status); |
@@ -895,9 +906,17 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
895 | (void)acpi_ev_add_gpe_reference(gpe_event_info); | 906 | (void)acpi_ev_add_gpe_reference(gpe_event_info); |
896 | } | 907 | } |
897 | 908 | ||
909 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
910 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
911 | |||
912 | /* Make sure all deferred GPE tasks are completed */ | ||
913 | |||
914 | acpi_os_wait_events_complete(); | ||
915 | |||
898 | /* Now we can free the handler object */ | 916 | /* Now we can free the handler object */ |
899 | 917 | ||
900 | ACPI_FREE(handler); | 918 | ACPI_FREE(handler); |
919 | return_ACPI_STATUS(status); | ||
901 | 920 | ||
902 | unlock_and_exit: | 921 | unlock_and_exit: |
903 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 922 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 20a1392ffe06..cb534faf5369 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c | |||
@@ -599,9 +599,10 @@ acpi_install_gpe_block(acpi_handle gpe_device, | |||
599 | * For user-installed GPE Block Devices, the gpe_block_base_number | 599 | * For user-installed GPE Block Devices, the gpe_block_base_number |
600 | * is always zero | 600 | * is always zero |
601 | */ | 601 | */ |
602 | status = | 602 | status = acpi_ev_create_gpe_block(node, gpe_block_address->address, |
603 | acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0, | 603 | gpe_block_address->space_id, |
604 | interrupt_number, &gpe_block); | 604 | register_count, 0, interrupt_number, |
605 | &gpe_block); | ||
605 | if (ACPI_FAILURE(status)) { | 606 | if (ACPI_FAILURE(status)) { |
606 | goto unlock_and_exit; | 607 | goto unlock_and_exit; |
607 | } | 608 | } |
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 8ba1464efd11..7d2949420db7 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
@@ -343,16 +343,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
343 | struct acpi_walk_state *walk_state) | 343 | struct acpi_walk_state *walk_state) |
344 | { | 344 | { |
345 | union acpi_operand_object *ddb_handle; | 345 | union acpi_operand_object *ddb_handle; |
346 | struct acpi_table_header *table_header; | ||
346 | struct acpi_table_header *table; | 347 | struct acpi_table_header *table; |
347 | struct acpi_table_desc table_desc; | ||
348 | u32 table_index; | 348 | u32 table_index; |
349 | acpi_status status; | 349 | acpi_status status; |
350 | u32 length; | 350 | u32 length; |
351 | 351 | ||
352 | ACPI_FUNCTION_TRACE(ex_load_op); | 352 | ACPI_FUNCTION_TRACE(ex_load_op); |
353 | 353 | ||
354 | ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); | ||
355 | |||
356 | /* Source Object can be either an op_region or a Buffer/Field */ | 354 | /* Source Object can be either an op_region or a Buffer/Field */ |
357 | 355 | ||
358 | switch (obj_desc->common.type) { | 356 | switch (obj_desc->common.type) { |
@@ -380,17 +378,17 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
380 | 378 | ||
381 | /* Get the table header first so we can get the table length */ | 379 | /* Get the table header first so we can get the table length */ |
382 | 380 | ||
383 | table = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); | 381 | table_header = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); |
384 | if (!table) { | 382 | if (!table_header) { |
385 | return_ACPI_STATUS(AE_NO_MEMORY); | 383 | return_ACPI_STATUS(AE_NO_MEMORY); |
386 | } | 384 | } |
387 | 385 | ||
388 | status = | 386 | status = |
389 | acpi_ex_region_read(obj_desc, | 387 | acpi_ex_region_read(obj_desc, |
390 | sizeof(struct acpi_table_header), | 388 | sizeof(struct acpi_table_header), |
391 | ACPI_CAST_PTR(u8, table)); | 389 | ACPI_CAST_PTR(u8, table_header)); |
392 | length = table->length; | 390 | length = table_header->length; |
393 | ACPI_FREE(table); | 391 | ACPI_FREE(table_header); |
394 | 392 | ||
395 | if (ACPI_FAILURE(status)) { | 393 | if (ACPI_FAILURE(status)) { |
396 | return_ACPI_STATUS(status); | 394 | return_ACPI_STATUS(status); |
@@ -420,22 +418,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
420 | 418 | ||
421 | /* Allocate a buffer for the table */ | 419 | /* Allocate a buffer for the table */ |
422 | 420 | ||
423 | table_desc.pointer = ACPI_ALLOCATE(length); | 421 | table = ACPI_ALLOCATE(length); |
424 | if (!table_desc.pointer) { | 422 | if (!table) { |
425 | return_ACPI_STATUS(AE_NO_MEMORY); | 423 | return_ACPI_STATUS(AE_NO_MEMORY); |
426 | } | 424 | } |
427 | 425 | ||
428 | /* Read the entire table */ | 426 | /* Read the entire table */ |
429 | 427 | ||
430 | status = acpi_ex_region_read(obj_desc, length, | 428 | status = acpi_ex_region_read(obj_desc, length, |
431 | ACPI_CAST_PTR(u8, | 429 | ACPI_CAST_PTR(u8, table)); |
432 | table_desc.pointer)); | ||
433 | if (ACPI_FAILURE(status)) { | 430 | if (ACPI_FAILURE(status)) { |
434 | ACPI_FREE(table_desc.pointer); | 431 | ACPI_FREE(table); |
435 | return_ACPI_STATUS(status); | 432 | return_ACPI_STATUS(status); |
436 | } | 433 | } |
437 | |||
438 | table_desc.address = obj_desc->region.address; | ||
439 | break; | 434 | break; |
440 | 435 | ||
441 | case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ | 436 | case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ |
@@ -452,10 +447,10 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
452 | 447 | ||
453 | /* Get the actual table length from the table header */ | 448 | /* Get the actual table length from the table header */ |
454 | 449 | ||
455 | table = | 450 | table_header = |
456 | ACPI_CAST_PTR(struct acpi_table_header, | 451 | ACPI_CAST_PTR(struct acpi_table_header, |
457 | obj_desc->buffer.pointer); | 452 | obj_desc->buffer.pointer); |
458 | length = table->length; | 453 | length = table_header->length; |
459 | 454 | ||
460 | /* Table cannot extend beyond the buffer */ | 455 | /* Table cannot extend beyond the buffer */ |
461 | 456 | ||
@@ -470,13 +465,12 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
470 | * Copy the table from the buffer because the buffer could be modified | 465 | * Copy the table from the buffer because the buffer could be modified |
471 | * or even deleted in the future | 466 | * or even deleted in the future |
472 | */ | 467 | */ |
473 | table_desc.pointer = ACPI_ALLOCATE(length); | 468 | table = ACPI_ALLOCATE(length); |
474 | if (!table_desc.pointer) { | 469 | if (!table) { |
475 | return_ACPI_STATUS(AE_NO_MEMORY); | 470 | return_ACPI_STATUS(AE_NO_MEMORY); |
476 | } | 471 | } |
477 | 472 | ||
478 | ACPI_MEMCPY(table_desc.pointer, table, length); | 473 | ACPI_MEMCPY(table, table_header, length); |
479 | table_desc.address = ACPI_TO_INTEGER(table_desc.pointer); | ||
480 | break; | 474 | break; |
481 | 475 | ||
482 | default: | 476 | default: |
@@ -484,27 +478,32 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
484 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 478 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
485 | } | 479 | } |
486 | 480 | ||
487 | /* Validate table checksum (will not get validated in tb_add_table) */ | 481 | /* Install the new table into the local data structures */ |
488 | |||
489 | status = acpi_tb_verify_checksum(table_desc.pointer, length); | ||
490 | if (ACPI_FAILURE(status)) { | ||
491 | ACPI_FREE(table_desc.pointer); | ||
492 | return_ACPI_STATUS(status); | ||
493 | } | ||
494 | |||
495 | /* Complete the table descriptor */ | ||
496 | 482 | ||
497 | table_desc.length = length; | 483 | ACPI_INFO((AE_INFO, "Dynamic OEM Table Load:")); |
498 | table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; | 484 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
499 | 485 | ||
500 | /* Install the new table into the local data structures */ | 486 | status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table), |
487 | ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, | ||
488 | TRUE, TRUE, &table_index); | ||
501 | 489 | ||
502 | status = acpi_tb_add_table(&table_desc, &table_index); | 490 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
503 | if (ACPI_FAILURE(status)) { | 491 | if (ACPI_FAILURE(status)) { |
504 | 492 | ||
505 | /* Delete allocated table buffer */ | 493 | /* Delete allocated table buffer */ |
506 | 494 | ||
507 | acpi_tb_delete_table(&table_desc); | 495 | ACPI_FREE(table); |
496 | return_ACPI_STATUS(status); | ||
497 | } | ||
498 | |||
499 | /* | ||
500 | * Note: Now table is "INSTALLED", it must be validated before | ||
501 | * loading. | ||
502 | */ | ||
503 | status = | ||
504 | acpi_tb_validate_table(&acpi_gbl_root_table_list. | ||
505 | tables[table_index]); | ||
506 | if (ACPI_FAILURE(status)) { | ||
508 | return_ACPI_STATUS(status); | 507 | return_ACPI_STATUS(status); |
509 | } | 508 | } |
510 | 509 | ||
@@ -536,9 +535,6 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
536 | return_ACPI_STATUS(status); | 535 | return_ACPI_STATUS(status); |
537 | } | 536 | } |
538 | 537 | ||
539 | ACPI_INFO((AE_INFO, "Dynamic OEM Table Load:")); | ||
540 | acpi_tb_print_table_header(0, table_desc.pointer); | ||
541 | |||
542 | /* Remove the reference by added by acpi_ex_store above */ | 538 | /* Remove the reference by added by acpi_ex_store above */ |
543 | 539 | ||
544 | acpi_ut_remove_reference(ddb_handle); | 540 | acpi_ut_remove_reference(ddb_handle); |
@@ -546,8 +542,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
546 | /* Invoke table handler if present */ | 542 | /* Invoke table handler if present */ |
547 | 543 | ||
548 | if (acpi_gbl_table_handler) { | 544 | if (acpi_gbl_table_handler) { |
549 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, | 545 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, |
550 | table_desc.pointer, | ||
551 | acpi_gbl_table_handler_context); | 546 | acpi_gbl_table_handler_context); |
552 | } | 547 | } |
553 | 548 | ||
@@ -576,6 +571,13 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
576 | ACPI_FUNCTION_TRACE(ex_unload_table); | 571 | ACPI_FUNCTION_TRACE(ex_unload_table); |
577 | 572 | ||
578 | /* | 573 | /* |
574 | * Temporarily emit a warning so that the ASL for the machine can be | ||
575 | * hopefully obtained. This is to say that the Unload() operator is | ||
576 | * extremely rare if not completely unused. | ||
577 | */ | ||
578 | ACPI_WARNING((AE_INFO, "Received request to unload an ACPI table")); | ||
579 | |||
580 | /* | ||
579 | * Validate the handle | 581 | * Validate the handle |
580 | * Although the handle is partially validated in acpi_ex_reconfiguration() | 582 | * Although the handle is partially validated in acpi_ex_reconfiguration() |
581 | * when it calls acpi_ex_resolve_operands(), the handle is more completely | 583 | * when it calls acpi_ex_resolve_operands(), the handle is more completely |
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 973fdae00f94..925202acc3e4 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c | |||
@@ -134,9 +134,11 @@ static struct acpi_exdump_info acpi_ex_dump_method[9] = { | |||
134 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"} | 134 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"} |
135 | }; | 135 | }; |
136 | 136 | ||
137 | static struct acpi_exdump_info acpi_ex_dump_mutex[5] = { | 137 | static struct acpi_exdump_info acpi_ex_dump_mutex[6] = { |
138 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL}, | 138 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL}, |
139 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"}, | 139 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"}, |
140 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.original_sync_level), | ||
141 | "Original Sync Level"}, | ||
140 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"}, | 142 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"}, |
141 | {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth), | 143 | {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth), |
142 | "Acquire Depth"}, | 144 | "Acquire Depth"}, |
diff --git a/drivers/acpi/acpica/hwpci.c b/drivers/acpi/acpica/hwpci.c index e701d8c33dbf..6aade8e1d2a1 100644 --- a/drivers/acpi/acpica/hwpci.c +++ b/drivers/acpi/acpica/hwpci.c | |||
@@ -140,11 +140,12 @@ acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, | |||
140 | /* Walk the list, updating the PCI device/function/bus numbers */ | 140 | /* Walk the list, updating the PCI device/function/bus numbers */ |
141 | 141 | ||
142 | status = acpi_hw_process_pci_list(pci_id, list_head); | 142 | status = acpi_hw_process_pci_list(pci_id, list_head); |
143 | } | ||
144 | 143 | ||
145 | /* Always delete the list */ | 144 | /* Delete the list */ |
145 | |||
146 | acpi_hw_delete_pci_list(list_head); | ||
147 | } | ||
146 | 148 | ||
147 | acpi_hw_delete_pci_list(list_head); | ||
148 | return_ACPI_STATUS(status); | 149 | return_ACPI_STATUS(status); |
149 | } | 150 | } |
150 | 151 | ||
@@ -187,6 +188,10 @@ acpi_hw_build_pci_list(acpi_handle root_pci_device, | |||
187 | while (1) { | 188 | while (1) { |
188 | status = acpi_get_parent(current_device, &parent_device); | 189 | status = acpi_get_parent(current_device, &parent_device); |
189 | if (ACPI_FAILURE(status)) { | 190 | if (ACPI_FAILURE(status)) { |
191 | |||
192 | /* Must delete the list before exit */ | ||
193 | |||
194 | acpi_hw_delete_pci_list(*return_list_head); | ||
190 | return (status); | 195 | return (status); |
191 | } | 196 | } |
192 | 197 | ||
@@ -199,6 +204,10 @@ acpi_hw_build_pci_list(acpi_handle root_pci_device, | |||
199 | 204 | ||
200 | list_element = ACPI_ALLOCATE(sizeof(struct acpi_pci_device)); | 205 | list_element = ACPI_ALLOCATE(sizeof(struct acpi_pci_device)); |
201 | if (!list_element) { | 206 | if (!list_element) { |
207 | |||
208 | /* Must delete the list before exit */ | ||
209 | |||
210 | acpi_hw_delete_pci_list(*return_list_head); | ||
202 | return (AE_NO_MEMORY); | 211 | return (AE_NO_MEMORY); |
203 | } | 212 | } |
204 | 213 | ||
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c index 75d369050657..049d9c22a0f9 100644 --- a/drivers/acpi/acpica/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c | |||
@@ -72,6 +72,8 @@ acpi_buffer_to_resource(u8 *aml_buffer, | |||
72 | void *resource; | 72 | void *resource; |
73 | void *current_resource_ptr; | 73 | void *current_resource_ptr; |
74 | 74 | ||
75 | ACPI_FUNCTION_TRACE(acpi_buffer_to_resource); | ||
76 | |||
75 | /* | 77 | /* |
76 | * Note: we allow AE_AML_NO_RESOURCE_END_TAG, since an end tag | 78 | * Note: we allow AE_AML_NO_RESOURCE_END_TAG, since an end tag |
77 | * is not required here. | 79 | * is not required here. |
@@ -85,7 +87,7 @@ acpi_buffer_to_resource(u8 *aml_buffer, | |||
85 | status = AE_OK; | 87 | status = AE_OK; |
86 | } | 88 | } |
87 | if (ACPI_FAILURE(status)) { | 89 | if (ACPI_FAILURE(status)) { |
88 | return (status); | 90 | return_ACPI_STATUS(status); |
89 | } | 91 | } |
90 | 92 | ||
91 | /* Allocate a buffer for the converted resource */ | 93 | /* Allocate a buffer for the converted resource */ |
@@ -93,7 +95,7 @@ acpi_buffer_to_resource(u8 *aml_buffer, | |||
93 | resource = ACPI_ALLOCATE_ZEROED(list_size_needed); | 95 | resource = ACPI_ALLOCATE_ZEROED(list_size_needed); |
94 | current_resource_ptr = resource; | 96 | current_resource_ptr = resource; |
95 | if (!resource) { | 97 | if (!resource) { |
96 | return (AE_NO_MEMORY); | 98 | return_ACPI_STATUS(AE_NO_MEMORY); |
97 | } | 99 | } |
98 | 100 | ||
99 | /* Perform the AML-to-Resource conversion */ | 101 | /* Perform the AML-to-Resource conversion */ |
@@ -110,9 +112,11 @@ acpi_buffer_to_resource(u8 *aml_buffer, | |||
110 | *resource_ptr = resource; | 112 | *resource_ptr = resource; |
111 | } | 113 | } |
112 | 114 | ||
113 | return (status); | 115 | return_ACPI_STATUS(status); |
114 | } | 116 | } |
115 | 117 | ||
118 | ACPI_EXPORT_SYMBOL(acpi_buffer_to_resource) | ||
119 | |||
116 | /******************************************************************************* | 120 | /******************************************************************************* |
117 | * | 121 | * |
118 | * FUNCTION: acpi_rs_create_resource_list | 122 | * FUNCTION: acpi_rs_create_resource_list |
@@ -130,10 +134,9 @@ acpi_buffer_to_resource(u8 *aml_buffer, | |||
130 | * of device resources. | 134 | * of device resources. |
131 | * | 135 | * |
132 | ******************************************************************************/ | 136 | ******************************************************************************/ |
133 | |||
134 | acpi_status | 137 | acpi_status |
135 | acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, | 138 | acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, |
136 | struct acpi_buffer * output_buffer) | 139 | struct acpi_buffer *output_buffer) |
137 | { | 140 | { |
138 | 141 | ||
139 | acpi_status status; | 142 | acpi_status status; |
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c new file mode 100644 index 000000000000..f499c10ceb4a --- /dev/null +++ b/drivers/acpi/acpica/tbdata.c | |||
@@ -0,0 +1,760 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbdata - Table manager data structure functions | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acnamesp.h" | ||
47 | #include "actables.h" | ||
48 | |||
49 | #define _COMPONENT ACPI_TABLES | ||
50 | ACPI_MODULE_NAME("tbdata") | ||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_tb_init_table_descriptor | ||
55 | * | ||
56 | * PARAMETERS: table_desc - Table descriptor | ||
57 | * address - Physical address of the table | ||
58 | * flags - Allocation flags of the table | ||
59 | * table - Pointer to the table | ||
60 | * | ||
61 | * RETURN: None | ||
62 | * | ||
63 | * DESCRIPTION: Initialize a new table descriptor | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | void | ||
67 | acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc, | ||
68 | acpi_physical_address address, | ||
69 | u8 flags, struct acpi_table_header *table) | ||
70 | { | ||
71 | |||
72 | /* | ||
73 | * Initialize the table descriptor. Set the pointer to NULL, since the | ||
74 | * table is not fully mapped at this time. | ||
75 | */ | ||
76 | ACPI_MEMSET(table_desc, 0, sizeof(struct acpi_table_desc)); | ||
77 | table_desc->address = address; | ||
78 | table_desc->length = table->length; | ||
79 | table_desc->flags = flags; | ||
80 | ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature); | ||
81 | } | ||
82 | |||
83 | /******************************************************************************* | ||
84 | * | ||
85 | * FUNCTION: acpi_tb_acquire_table | ||
86 | * | ||
87 | * PARAMETERS: table_desc - Table descriptor | ||
88 | * table_ptr - Where table is returned | ||
89 | * table_length - Where table length is returned | ||
90 | * table_flags - Where table allocation flags are returned | ||
91 | * | ||
92 | * RETURN: Status | ||
93 | * | ||
94 | * DESCRIPTION: Acquire an ACPI table. It can be used for tables not | ||
95 | * maintained in the acpi_gbl_root_table_list. | ||
96 | * | ||
97 | ******************************************************************************/ | ||
98 | |||
99 | acpi_status | ||
100 | acpi_tb_acquire_table(struct acpi_table_desc *table_desc, | ||
101 | struct acpi_table_header **table_ptr, | ||
102 | u32 *table_length, u8 *table_flags) | ||
103 | { | ||
104 | struct acpi_table_header *table = NULL; | ||
105 | |||
106 | switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { | ||
107 | case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: | ||
108 | |||
109 | table = | ||
110 | acpi_os_map_memory(table_desc->address, table_desc->length); | ||
111 | break; | ||
112 | |||
113 | case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: | ||
114 | case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: | ||
115 | |||
116 | table = | ||
117 | ACPI_CAST_PTR(struct acpi_table_header, | ||
118 | table_desc->address); | ||
119 | break; | ||
120 | |||
121 | default: | ||
122 | |||
123 | break; | ||
124 | } | ||
125 | |||
126 | /* Table is not valid yet */ | ||
127 | |||
128 | if (!table) { | ||
129 | return (AE_NO_MEMORY); | ||
130 | } | ||
131 | |||
132 | /* Fill the return values */ | ||
133 | |||
134 | *table_ptr = table; | ||
135 | *table_length = table_desc->length; | ||
136 | *table_flags = table_desc->flags; | ||
137 | return (AE_OK); | ||
138 | } | ||
139 | |||
140 | /******************************************************************************* | ||
141 | * | ||
142 | * FUNCTION: acpi_tb_release_table | ||
143 | * | ||
144 | * PARAMETERS: table - Pointer for the table | ||
145 | * table_length - Length for the table | ||
146 | * table_flags - Allocation flags for the table | ||
147 | * | ||
148 | * RETURN: None | ||
149 | * | ||
150 | * DESCRIPTION: Release a table. The inverse of acpi_tb_acquire_table(). | ||
151 | * | ||
152 | ******************************************************************************/ | ||
153 | |||
154 | void | ||
155 | acpi_tb_release_table(struct acpi_table_header *table, | ||
156 | u32 table_length, u8 table_flags) | ||
157 | { | ||
158 | |||
159 | switch (table_flags & ACPI_TABLE_ORIGIN_MASK) { | ||
160 | case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: | ||
161 | |||
162 | acpi_os_unmap_memory(table, table_length); | ||
163 | break; | ||
164 | |||
165 | case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: | ||
166 | case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: | ||
167 | default: | ||
168 | |||
169 | break; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | /******************************************************************************* | ||
174 | * | ||
175 | * FUNCTION: acpi_tb_acquire_temp_table | ||
176 | * | ||
177 | * PARAMETERS: table_desc - Table descriptor to be acquired | ||
178 | * address - Address of the table | ||
179 | * flags - Allocation flags of the table | ||
180 | * | ||
181 | * RETURN: Status | ||
182 | * | ||
183 | * DESCRIPTION: This function validates the table header to obtain the length | ||
184 | * of a table and fills the table descriptor to make its state as | ||
185 | * "INSTALLED". Such a table descriptor is only used for verified | ||
186 | * installation. | ||
187 | * | ||
188 | ******************************************************************************/ | ||
189 | |||
190 | acpi_status | ||
191 | acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc, | ||
192 | acpi_physical_address address, u8 flags) | ||
193 | { | ||
194 | struct acpi_table_header *table_header; | ||
195 | |||
196 | switch (flags & ACPI_TABLE_ORIGIN_MASK) { | ||
197 | case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: | ||
198 | |||
199 | /* Get the length of the full table from the header */ | ||
200 | |||
201 | table_header = | ||
202 | acpi_os_map_memory(address, | ||
203 | sizeof(struct acpi_table_header)); | ||
204 | if (!table_header) { | ||
205 | return (AE_NO_MEMORY); | ||
206 | } | ||
207 | |||
208 | acpi_tb_init_table_descriptor(table_desc, address, flags, | ||
209 | table_header); | ||
210 | acpi_os_unmap_memory(table_header, | ||
211 | sizeof(struct acpi_table_header)); | ||
212 | return (AE_OK); | ||
213 | |||
214 | case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: | ||
215 | case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: | ||
216 | |||
217 | table_header = ACPI_CAST_PTR(struct acpi_table_header, address); | ||
218 | if (!table_header) { | ||
219 | return (AE_NO_MEMORY); | ||
220 | } | ||
221 | |||
222 | acpi_tb_init_table_descriptor(table_desc, address, flags, | ||
223 | table_header); | ||
224 | return (AE_OK); | ||
225 | |||
226 | default: | ||
227 | |||
228 | break; | ||
229 | } | ||
230 | |||
231 | /* Table is not valid yet */ | ||
232 | |||
233 | return (AE_NO_MEMORY); | ||
234 | } | ||
235 | |||
236 | /******************************************************************************* | ||
237 | * | ||
238 | * FUNCTION: acpi_tb_release_temp_table | ||
239 | * | ||
240 | * PARAMETERS: table_desc - Table descriptor to be released | ||
241 | * | ||
242 | * RETURN: Status | ||
243 | * | ||
244 | * DESCRIPTION: The inverse of acpi_tb_acquire_temp_table(). | ||
245 | * | ||
246 | *****************************************************************************/ | ||
247 | |||
248 | void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc) | ||
249 | { | ||
250 | |||
251 | /* | ||
252 | * Note that the .Address is maintained by the callers of | ||
253 | * acpi_tb_acquire_temp_table(), thus do not invoke acpi_tb_uninstall_table() | ||
254 | * where .Address will be freed. | ||
255 | */ | ||
256 | acpi_tb_invalidate_table(table_desc); | ||
257 | } | ||
258 | |||
259 | /****************************************************************************** | ||
260 | * | ||
261 | * FUNCTION: acpi_tb_validate_table | ||
262 | * | ||
263 | * PARAMETERS: table_desc - Table descriptor | ||
264 | * | ||
265 | * RETURN: Status | ||
266 | * | ||
267 | * DESCRIPTION: This function is called to validate the table, the returned | ||
268 | * table descriptor is in "VALIDATED" state. | ||
269 | * | ||
270 | *****************************************************************************/ | ||
271 | |||
272 | acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc) | ||
273 | { | ||
274 | acpi_status status = AE_OK; | ||
275 | |||
276 | ACPI_FUNCTION_TRACE(tb_validate_table); | ||
277 | |||
278 | /* Validate the table if necessary */ | ||
279 | |||
280 | if (!table_desc->pointer) { | ||
281 | status = acpi_tb_acquire_table(table_desc, &table_desc->pointer, | ||
282 | &table_desc->length, | ||
283 | &table_desc->flags); | ||
284 | if (!table_desc->pointer) { | ||
285 | status = AE_NO_MEMORY; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | return_ACPI_STATUS(status); | ||
290 | } | ||
291 | |||
292 | /******************************************************************************* | ||
293 | * | ||
294 | * FUNCTION: acpi_tb_invalidate_table | ||
295 | * | ||
296 | * PARAMETERS: table_desc - Table descriptor | ||
297 | * | ||
298 | * RETURN: None | ||
299 | * | ||
300 | * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of | ||
301 | * acpi_tb_validate_table(). | ||
302 | * | ||
303 | ******************************************************************************/ | ||
304 | |||
305 | void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc) | ||
306 | { | ||
307 | |||
308 | ACPI_FUNCTION_TRACE(tb_invalidate_table); | ||
309 | |||
310 | /* Table must be validated */ | ||
311 | |||
312 | if (!table_desc->pointer) { | ||
313 | return_VOID; | ||
314 | } | ||
315 | |||
316 | acpi_tb_release_table(table_desc->pointer, table_desc->length, | ||
317 | table_desc->flags); | ||
318 | table_desc->pointer = NULL; | ||
319 | |||
320 | return_VOID; | ||
321 | } | ||
322 | |||
323 | /****************************************************************************** | ||
324 | * | ||
325 | * FUNCTION: acpi_tb_validate_temp_table | ||
326 | * | ||
327 | * PARAMETERS: table_desc - Table descriptor | ||
328 | * | ||
329 | * RETURN: Status | ||
330 | * | ||
331 | * DESCRIPTION: This function is called to validate the table, the returned | ||
332 | * table descriptor is in "VALIDATED" state. | ||
333 | * | ||
334 | *****************************************************************************/ | ||
335 | |||
336 | acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc) | ||
337 | { | ||
338 | |||
339 | if (!table_desc->pointer && !acpi_gbl_verify_table_checksum) { | ||
340 | /* | ||
341 | * Only validates the header of the table. | ||
342 | * Note that Length contains the size of the mapping after invoking | ||
343 | * this work around, this value is required by | ||
344 | * acpi_tb_release_temp_table(). | ||
345 | * We can do this because in acpi_init_table_descriptor(), the Length | ||
346 | * field of the installed descriptor is filled with the actual | ||
347 | * table length obtaining from the table header. | ||
348 | */ | ||
349 | table_desc->length = sizeof(struct acpi_table_header); | ||
350 | } | ||
351 | |||
352 | return (acpi_tb_validate_table(table_desc)); | ||
353 | } | ||
354 | |||
355 | /****************************************************************************** | ||
356 | * | ||
357 | * FUNCTION: acpi_tb_verify_temp_table | ||
358 | * | ||
359 | * PARAMETERS: table_desc - Table descriptor | ||
360 | * signature - Table signature to verify | ||
361 | * | ||
362 | * RETURN: Status | ||
363 | * | ||
364 | * DESCRIPTION: This function is called to validate and verify the table, the | ||
365 | * returned table descriptor is in "VALIDATED" state. | ||
366 | * | ||
367 | *****************************************************************************/ | ||
368 | |||
369 | acpi_status | ||
370 | acpi_tb_verify_temp_table(struct acpi_table_desc * table_desc, char *signature) | ||
371 | { | ||
372 | acpi_status status = AE_OK; | ||
373 | |||
374 | ACPI_FUNCTION_TRACE(tb_verify_temp_table); | ||
375 | |||
376 | /* Validate the table */ | ||
377 | |||
378 | status = acpi_tb_validate_temp_table(table_desc); | ||
379 | if (ACPI_FAILURE(status)) { | ||
380 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
381 | } | ||
382 | |||
383 | /* If a particular signature is expected (DSDT/FACS), it must match */ | ||
384 | |||
385 | if (signature && !ACPI_COMPARE_NAME(&table_desc->signature, signature)) { | ||
386 | ACPI_BIOS_ERROR((AE_INFO, | ||
387 | "Invalid signature 0x%X for ACPI table, expected [%s]", | ||
388 | table_desc->signature.integer, signature)); | ||
389 | status = AE_BAD_SIGNATURE; | ||
390 | goto invalidate_and_exit; | ||
391 | } | ||
392 | |||
393 | /* Verify the checksum */ | ||
394 | |||
395 | if (acpi_gbl_verify_table_checksum) { | ||
396 | status = | ||
397 | acpi_tb_verify_checksum(table_desc->pointer, | ||
398 | table_desc->length); | ||
399 | if (ACPI_FAILURE(status)) { | ||
400 | ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, | ||
401 | "%4.4s " ACPI_PRINTF_UINT | ||
402 | " Attempted table install failed", | ||
403 | acpi_ut_valid_acpi_name(table_desc-> | ||
404 | signature. | ||
405 | ascii) ? | ||
406 | table_desc->signature.ascii : "????", | ||
407 | ACPI_FORMAT_TO_UINT(table_desc-> | ||
408 | address))); | ||
409 | goto invalidate_and_exit; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | return_ACPI_STATUS(AE_OK); | ||
414 | |||
415 | invalidate_and_exit: | ||
416 | acpi_tb_invalidate_table(table_desc); | ||
417 | return_ACPI_STATUS(status); | ||
418 | } | ||
419 | |||
420 | /******************************************************************************* | ||
421 | * | ||
422 | * FUNCTION: acpi_tb_resize_root_table_list | ||
423 | * | ||
424 | * PARAMETERS: None | ||
425 | * | ||
426 | * RETURN: Status | ||
427 | * | ||
428 | * DESCRIPTION: Expand the size of global table array | ||
429 | * | ||
430 | ******************************************************************************/ | ||
431 | |||
432 | acpi_status acpi_tb_resize_root_table_list(void) | ||
433 | { | ||
434 | struct acpi_table_desc *tables; | ||
435 | u32 table_count; | ||
436 | |||
437 | ACPI_FUNCTION_TRACE(tb_resize_root_table_list); | ||
438 | |||
439 | /* allow_resize flag is a parameter to acpi_initialize_tables */ | ||
440 | |||
441 | if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { | ||
442 | ACPI_ERROR((AE_INFO, | ||
443 | "Resize of Root Table Array is not allowed")); | ||
444 | return_ACPI_STATUS(AE_SUPPORT); | ||
445 | } | ||
446 | |||
447 | /* Increase the Table Array size */ | ||
448 | |||
449 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | ||
450 | table_count = acpi_gbl_root_table_list.max_table_count; | ||
451 | } else { | ||
452 | table_count = acpi_gbl_root_table_list.current_table_count; | ||
453 | } | ||
454 | |||
455 | tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count + | ||
456 | ACPI_ROOT_TABLE_SIZE_INCREMENT) * | ||
457 | sizeof(struct acpi_table_desc)); | ||
458 | if (!tables) { | ||
459 | ACPI_ERROR((AE_INFO, | ||
460 | "Could not allocate new root table array")); | ||
461 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
462 | } | ||
463 | |||
464 | /* Copy and free the previous table array */ | ||
465 | |||
466 | if (acpi_gbl_root_table_list.tables) { | ||
467 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, | ||
468 | (acpi_size) table_count * | ||
469 | sizeof(struct acpi_table_desc)); | ||
470 | |||
471 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | ||
472 | ACPI_FREE(acpi_gbl_root_table_list.tables); | ||
473 | } | ||
474 | } | ||
475 | |||
476 | acpi_gbl_root_table_list.tables = tables; | ||
477 | acpi_gbl_root_table_list.max_table_count = | ||
478 | table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT; | ||
479 | acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED; | ||
480 | |||
481 | return_ACPI_STATUS(AE_OK); | ||
482 | } | ||
483 | |||
484 | /******************************************************************************* | ||
485 | * | ||
486 | * FUNCTION: acpi_tb_get_next_root_index | ||
487 | * | ||
488 | * PARAMETERS: table_index - Where table index is returned | ||
489 | * | ||
490 | * RETURN: Status and table index. | ||
491 | * | ||
492 | * DESCRIPTION: Allocate a new ACPI table entry to the global table list | ||
493 | * | ||
494 | ******************************************************************************/ | ||
495 | |||
496 | acpi_status acpi_tb_get_next_root_index(u32 *table_index) | ||
497 | { | ||
498 | acpi_status status; | ||
499 | |||
500 | /* Ensure that there is room for the table in the Root Table List */ | ||
501 | |||
502 | if (acpi_gbl_root_table_list.current_table_count >= | ||
503 | acpi_gbl_root_table_list.max_table_count) { | ||
504 | status = acpi_tb_resize_root_table_list(); | ||
505 | if (ACPI_FAILURE(status)) { | ||
506 | return (status); | ||
507 | } | ||
508 | } | ||
509 | |||
510 | *table_index = acpi_gbl_root_table_list.current_table_count; | ||
511 | acpi_gbl_root_table_list.current_table_count++; | ||
512 | return (AE_OK); | ||
513 | } | ||
514 | |||
515 | /******************************************************************************* | ||
516 | * | ||
517 | * FUNCTION: acpi_tb_terminate | ||
518 | * | ||
519 | * PARAMETERS: None | ||
520 | * | ||
521 | * RETURN: None | ||
522 | * | ||
523 | * DESCRIPTION: Delete all internal ACPI tables | ||
524 | * | ||
525 | ******************************************************************************/ | ||
526 | |||
527 | void acpi_tb_terminate(void) | ||
528 | { | ||
529 | u32 i; | ||
530 | |||
531 | ACPI_FUNCTION_TRACE(tb_terminate); | ||
532 | |||
533 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
534 | |||
535 | /* Delete the individual tables */ | ||
536 | |||
537 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { | ||
538 | acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]); | ||
539 | } | ||
540 | |||
541 | /* | ||
542 | * Delete the root table array if allocated locally. Array cannot be | ||
543 | * mapped, so we don't need to check for that flag. | ||
544 | */ | ||
545 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | ||
546 | ACPI_FREE(acpi_gbl_root_table_list.tables); | ||
547 | } | ||
548 | |||
549 | acpi_gbl_root_table_list.tables = NULL; | ||
550 | acpi_gbl_root_table_list.flags = 0; | ||
551 | acpi_gbl_root_table_list.current_table_count = 0; | ||
552 | |||
553 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); | ||
554 | |||
555 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
556 | return_VOID; | ||
557 | } | ||
558 | |||
559 | /******************************************************************************* | ||
560 | * | ||
561 | * FUNCTION: acpi_tb_delete_namespace_by_owner | ||
562 | * | ||
563 | * PARAMETERS: table_index - Table index | ||
564 | * | ||
565 | * RETURN: Status | ||
566 | * | ||
567 | * DESCRIPTION: Delete all namespace objects created when this table was loaded. | ||
568 | * | ||
569 | ******************************************************************************/ | ||
570 | |||
571 | acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) | ||
572 | { | ||
573 | acpi_owner_id owner_id; | ||
574 | acpi_status status; | ||
575 | |||
576 | ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner); | ||
577 | |||
578 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
579 | if (ACPI_FAILURE(status)) { | ||
580 | return_ACPI_STATUS(status); | ||
581 | } | ||
582 | |||
583 | if (table_index >= acpi_gbl_root_table_list.current_table_count) { | ||
584 | |||
585 | /* The table index does not exist */ | ||
586 | |||
587 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
588 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
589 | } | ||
590 | |||
591 | /* Get the owner ID for this table, used to delete namespace nodes */ | ||
592 | |||
593 | owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
594 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
595 | |||
596 | /* | ||
597 | * Need to acquire the namespace writer lock to prevent interference | ||
598 | * with any concurrent namespace walks. The interpreter must be | ||
599 | * released during the deletion since the acquisition of the deletion | ||
600 | * lock may block, and also since the execution of a namespace walk | ||
601 | * must be allowed to use the interpreter. | ||
602 | */ | ||
603 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | ||
604 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); | ||
605 | |||
606 | acpi_ns_delete_namespace_by_owner(owner_id); | ||
607 | if (ACPI_FAILURE(status)) { | ||
608 | return_ACPI_STATUS(status); | ||
609 | } | ||
610 | |||
611 | acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); | ||
612 | |||
613 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | ||
614 | return_ACPI_STATUS(status); | ||
615 | } | ||
616 | |||
617 | /******************************************************************************* | ||
618 | * | ||
619 | * FUNCTION: acpi_tb_allocate_owner_id | ||
620 | * | ||
621 | * PARAMETERS: table_index - Table index | ||
622 | * | ||
623 | * RETURN: Status | ||
624 | * | ||
625 | * DESCRIPTION: Allocates owner_id in table_desc | ||
626 | * | ||
627 | ******************************************************************************/ | ||
628 | |||
629 | acpi_status acpi_tb_allocate_owner_id(u32 table_index) | ||
630 | { | ||
631 | acpi_status status = AE_BAD_PARAMETER; | ||
632 | |||
633 | ACPI_FUNCTION_TRACE(tb_allocate_owner_id); | ||
634 | |||
635 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
636 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
637 | status = | ||
638 | acpi_ut_allocate_owner_id(& | ||
639 | (acpi_gbl_root_table_list. | ||
640 | tables[table_index].owner_id)); | ||
641 | } | ||
642 | |||
643 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
644 | return_ACPI_STATUS(status); | ||
645 | } | ||
646 | |||
647 | /******************************************************************************* | ||
648 | * | ||
649 | * FUNCTION: acpi_tb_release_owner_id | ||
650 | * | ||
651 | * PARAMETERS: table_index - Table index | ||
652 | * | ||
653 | * RETURN: Status | ||
654 | * | ||
655 | * DESCRIPTION: Releases owner_id in table_desc | ||
656 | * | ||
657 | ******************************************************************************/ | ||
658 | |||
659 | acpi_status acpi_tb_release_owner_id(u32 table_index) | ||
660 | { | ||
661 | acpi_status status = AE_BAD_PARAMETER; | ||
662 | |||
663 | ACPI_FUNCTION_TRACE(tb_release_owner_id); | ||
664 | |||
665 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
666 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
667 | acpi_ut_release_owner_id(& | ||
668 | (acpi_gbl_root_table_list. | ||
669 | tables[table_index].owner_id)); | ||
670 | status = AE_OK; | ||
671 | } | ||
672 | |||
673 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
674 | return_ACPI_STATUS(status); | ||
675 | } | ||
676 | |||
677 | /******************************************************************************* | ||
678 | * | ||
679 | * FUNCTION: acpi_tb_get_owner_id | ||
680 | * | ||
681 | * PARAMETERS: table_index - Table index | ||
682 | * owner_id - Where the table owner_id is returned | ||
683 | * | ||
684 | * RETURN: Status | ||
685 | * | ||
686 | * DESCRIPTION: returns owner_id for the ACPI table | ||
687 | * | ||
688 | ******************************************************************************/ | ||
689 | |||
690 | acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id * owner_id) | ||
691 | { | ||
692 | acpi_status status = AE_BAD_PARAMETER; | ||
693 | |||
694 | ACPI_FUNCTION_TRACE(tb_get_owner_id); | ||
695 | |||
696 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
697 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
698 | *owner_id = | ||
699 | acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
700 | status = AE_OK; | ||
701 | } | ||
702 | |||
703 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
704 | return_ACPI_STATUS(status); | ||
705 | } | ||
706 | |||
707 | /******************************************************************************* | ||
708 | * | ||
709 | * FUNCTION: acpi_tb_is_table_loaded | ||
710 | * | ||
711 | * PARAMETERS: table_index - Index into the root table | ||
712 | * | ||
713 | * RETURN: Table Loaded Flag | ||
714 | * | ||
715 | ******************************************************************************/ | ||
716 | |||
717 | u8 acpi_tb_is_table_loaded(u32 table_index) | ||
718 | { | ||
719 | u8 is_loaded = FALSE; | ||
720 | |||
721 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
722 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
723 | is_loaded = (u8) | ||
724 | (acpi_gbl_root_table_list.tables[table_index].flags & | ||
725 | ACPI_TABLE_IS_LOADED); | ||
726 | } | ||
727 | |||
728 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
729 | return (is_loaded); | ||
730 | } | ||
731 | |||
732 | /******************************************************************************* | ||
733 | * | ||
734 | * FUNCTION: acpi_tb_set_table_loaded_flag | ||
735 | * | ||
736 | * PARAMETERS: table_index - Table index | ||
737 | * is_loaded - TRUE if table is loaded, FALSE otherwise | ||
738 | * | ||
739 | * RETURN: None | ||
740 | * | ||
741 | * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. | ||
742 | * | ||
743 | ******************************************************************************/ | ||
744 | |||
745 | void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) | ||
746 | { | ||
747 | |||
748 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
749 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
750 | if (is_loaded) { | ||
751 | acpi_gbl_root_table_list.tables[table_index].flags |= | ||
752 | ACPI_TABLE_IS_LOADED; | ||
753 | } else { | ||
754 | acpi_gbl_root_table_list.tables[table_index].flags &= | ||
755 | ~ACPI_TABLE_IS_LOADED; | ||
756 | } | ||
757 | } | ||
758 | |||
759 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
760 | } | ||
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index ec14588254d4..41519a958083 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c | |||
@@ -52,7 +52,8 @@ ACPI_MODULE_NAME("tbfadt") | |||
52 | static void | 52 | static void |
53 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | 53 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, |
54 | u8 space_id, | 54 | u8 space_id, |
55 | u8 byte_width, u64 address, char *register_name); | 55 | u8 byte_width, |
56 | u64 address, char *register_name, u8 flags); | ||
56 | 57 | ||
57 | static void acpi_tb_convert_fadt(void); | 58 | static void acpi_tb_convert_fadt(void); |
58 | 59 | ||
@@ -69,13 +70,14 @@ typedef struct acpi_fadt_info { | |||
69 | u16 address32; | 70 | u16 address32; |
70 | u16 length; | 71 | u16 length; |
71 | u8 default_length; | 72 | u8 default_length; |
72 | u8 type; | 73 | u8 flags; |
73 | 74 | ||
74 | } acpi_fadt_info; | 75 | } acpi_fadt_info; |
75 | 76 | ||
76 | #define ACPI_FADT_OPTIONAL 0 | 77 | #define ACPI_FADT_OPTIONAL 0 |
77 | #define ACPI_FADT_REQUIRED 1 | 78 | #define ACPI_FADT_REQUIRED 1 |
78 | #define ACPI_FADT_SEPARATE_LENGTH 2 | 79 | #define ACPI_FADT_SEPARATE_LENGTH 2 |
80 | #define ACPI_FADT_GPE_REGISTER 4 | ||
79 | 81 | ||
80 | static struct acpi_fadt_info fadt_info_table[] = { | 82 | static struct acpi_fadt_info fadt_info_table[] = { |
81 | {"Pm1aEventBlock", | 83 | {"Pm1aEventBlock", |
@@ -125,14 +127,14 @@ static struct acpi_fadt_info fadt_info_table[] = { | |||
125 | ACPI_FADT_OFFSET(gpe0_block), | 127 | ACPI_FADT_OFFSET(gpe0_block), |
126 | ACPI_FADT_OFFSET(gpe0_block_length), | 128 | ACPI_FADT_OFFSET(gpe0_block_length), |
127 | 0, | 129 | 0, |
128 | ACPI_FADT_SEPARATE_LENGTH}, | 130 | ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER}, |
129 | 131 | ||
130 | {"Gpe1Block", | 132 | {"Gpe1Block", |
131 | ACPI_FADT_OFFSET(xgpe1_block), | 133 | ACPI_FADT_OFFSET(xgpe1_block), |
132 | ACPI_FADT_OFFSET(gpe1_block), | 134 | ACPI_FADT_OFFSET(gpe1_block), |
133 | ACPI_FADT_OFFSET(gpe1_block_length), | 135 | ACPI_FADT_OFFSET(gpe1_block_length), |
134 | 0, | 136 | 0, |
135 | ACPI_FADT_SEPARATE_LENGTH} | 137 | ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER} |
136 | }; | 138 | }; |
137 | 139 | ||
138 | #define ACPI_FADT_INFO_ENTRIES \ | 140 | #define ACPI_FADT_INFO_ENTRIES \ |
@@ -189,19 +191,29 @@ static struct acpi_fadt_pm_info fadt_pm_info_table[] = { | |||
189 | static void | 191 | static void |
190 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | 192 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, |
191 | u8 space_id, | 193 | u8 space_id, |
192 | u8 byte_width, u64 address, char *register_name) | 194 | u8 byte_width, |
195 | u64 address, char *register_name, u8 flags) | ||
193 | { | 196 | { |
194 | u8 bit_width; | 197 | u8 bit_width; |
195 | 198 | ||
196 | /* Bit width field in the GAS is only one byte long, 255 max */ | 199 | /* |
197 | 200 | * Bit width field in the GAS is only one byte long, 255 max. | |
201 | * Check for bit_width overflow in GAS. | ||
202 | */ | ||
198 | bit_width = (u8)(byte_width * 8); | 203 | bit_width = (u8)(byte_width * 8); |
199 | 204 | if (byte_width > 31) { /* (31*8)=248, (32*8)=256 */ | |
200 | if (byte_width > 31) { /* (31*8)=248 */ | 205 | /* |
201 | ACPI_ERROR((AE_INFO, | 206 | * No error for GPE blocks, because we do not use the bit_width |
202 | "%s - 32-bit FADT register is too long (%u bytes, %u bits) " | 207 | * for GPEs, the legacy length (byte_width) is used instead to |
203 | "to convert to GAS struct - 255 bits max, truncating", | 208 | * allow for a large number of GPEs. |
204 | register_name, byte_width, (byte_width * 8))); | 209 | */ |
210 | if (!(flags & ACPI_FADT_GPE_REGISTER)) { | ||
211 | ACPI_ERROR((AE_INFO, | ||
212 | "%s - 32-bit FADT register is too long (%u bytes, %u bits) " | ||
213 | "to convert to GAS struct - 255 bits max, truncating", | ||
214 | register_name, byte_width, | ||
215 | (byte_width * 8))); | ||
216 | } | ||
205 | 217 | ||
206 | bit_width = 255; | 218 | bit_width = 255; |
207 | } | 219 | } |
@@ -332,15 +344,15 @@ void acpi_tb_parse_fadt(u32 table_index) | |||
332 | 344 | ||
333 | /* Obtain the DSDT and FACS tables via their addresses within the FADT */ | 345 | /* Obtain the DSDT and FACS tables via their addresses within the FADT */ |
334 | 346 | ||
335 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, | 347 | acpi_tb_install_fixed_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, |
336 | ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); | 348 | ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); |
337 | 349 | ||
338 | /* If Hardware Reduced flag is set, there is no FACS */ | 350 | /* If Hardware Reduced flag is set, there is no FACS */ |
339 | 351 | ||
340 | if (!acpi_gbl_reduced_hardware) { | 352 | if (!acpi_gbl_reduced_hardware) { |
341 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT. | 353 | acpi_tb_install_fixed_table((acpi_physical_address) |
342 | Xfacs, ACPI_SIG_FACS, | 354 | acpi_gbl_FADT.Xfacs, ACPI_SIG_FACS, |
343 | ACPI_TABLE_INDEX_FACS); | 355 | ACPI_TABLE_INDEX_FACS); |
344 | } | 356 | } |
345 | } | 357 | } |
346 | 358 | ||
@@ -450,6 +462,7 @@ static void acpi_tb_convert_fadt(void) | |||
450 | struct acpi_generic_address *address64; | 462 | struct acpi_generic_address *address64; |
451 | u32 address32; | 463 | u32 address32; |
452 | u8 length; | 464 | u8 length; |
465 | u8 flags; | ||
453 | u32 i; | 466 | u32 i; |
454 | 467 | ||
455 | /* | 468 | /* |
@@ -515,6 +528,7 @@ static void acpi_tb_convert_fadt(void) | |||
515 | fadt_info_table[i].length); | 528 | fadt_info_table[i].length); |
516 | 529 | ||
517 | name = fadt_info_table[i].name; | 530 | name = fadt_info_table[i].name; |
531 | flags = fadt_info_table[i].flags; | ||
518 | 532 | ||
519 | /* | 533 | /* |
520 | * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" | 534 | * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" |
@@ -554,7 +568,7 @@ static void acpi_tb_convert_fadt(void) | |||
554 | [i]. | 568 | [i]. |
555 | length), | 569 | length), |
556 | (u64)address32, | 570 | (u64)address32, |
557 | name); | 571 | name, flags); |
558 | } else if (address64->address != (u64)address32) { | 572 | } else if (address64->address != (u64)address32) { |
559 | 573 | ||
560 | /* Address mismatch */ | 574 | /* Address mismatch */ |
@@ -582,7 +596,8 @@ static void acpi_tb_convert_fadt(void) | |||
582 | length), | 596 | length), |
583 | (u64) | 597 | (u64) |
584 | address32, | 598 | address32, |
585 | name); | 599 | name, |
600 | flags); | ||
586 | } | 601 | } |
587 | } | 602 | } |
588 | } | 603 | } |
@@ -603,7 +618,7 @@ static void acpi_tb_convert_fadt(void) | |||
603 | address64->bit_width)); | 618 | address64->bit_width)); |
604 | } | 619 | } |
605 | 620 | ||
606 | if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) { | 621 | if (fadt_info_table[i].flags & ACPI_FADT_REQUIRED) { |
607 | /* | 622 | /* |
608 | * Field is required (Pm1a_event, Pm1a_control). | 623 | * Field is required (Pm1a_event, Pm1a_control). |
609 | * Both the address and length must be non-zero. | 624 | * Both the address and length must be non-zero. |
@@ -617,7 +632,7 @@ static void acpi_tb_convert_fadt(void) | |||
617 | address), | 632 | address), |
618 | length)); | 633 | length)); |
619 | } | 634 | } |
620 | } else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) { | 635 | } else if (fadt_info_table[i].flags & ACPI_FADT_SEPARATE_LENGTH) { |
621 | /* | 636 | /* |
622 | * Field is optional (Pm2_control, GPE0, GPE1) AND has its own | 637 | * Field is optional (Pm2_control, GPE0, GPE1) AND has its own |
623 | * length field. If present, both the address and length must | 638 | * length field. If present, both the address and length must |
@@ -726,7 +741,7 @@ static void acpi_tb_setup_fadt_registers(void) | |||
726 | (fadt_pm_info_table[i]. | 741 | (fadt_pm_info_table[i]. |
727 | register_num * | 742 | register_num * |
728 | pm1_register_byte_width), | 743 | pm1_register_byte_width), |
729 | "PmRegisters"); | 744 | "PmRegisters", 0); |
730 | } | 745 | } |
731 | } | 746 | } |
732 | } | 747 | } |
diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index c12003947bd5..cb947700206c 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c | |||
@@ -99,8 +99,8 @@ acpi_tb_find_table(char *signature, | |||
99 | /* Table is not currently mapped, map it */ | 99 | /* Table is not currently mapped, map it */ |
100 | 100 | ||
101 | status = | 101 | status = |
102 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | 102 | acpi_tb_validate_table(&acpi_gbl_root_table_list. |
103 | tables[i]); | 103 | tables[i]); |
104 | if (ACPI_FAILURE(status)) { | 104 | if (ACPI_FAILURE(status)) { |
105 | return_ACPI_STATUS(status); | 105 | return_ACPI_STATUS(status); |
106 | } | 106 | } |
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index e3040947e9a0..755b90c40ddf 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
@@ -43,688 +43,483 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acnamesp.h" | ||
47 | #include "actables.h" | 46 | #include "actables.h" |
48 | 47 | ||
49 | #define _COMPONENT ACPI_TABLES | 48 | #define _COMPONENT ACPI_TABLES |
50 | ACPI_MODULE_NAME("tbinstal") | 49 | ACPI_MODULE_NAME("tbinstal") |
51 | 50 | ||
52 | /****************************************************************************** | 51 | /* Local prototypes */ |
52 | static u8 | ||
53 | acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index); | ||
54 | |||
55 | /******************************************************************************* | ||
53 | * | 56 | * |
54 | * FUNCTION: acpi_tb_verify_table | 57 | * FUNCTION: acpi_tb_compare_tables |
55 | * | 58 | * |
56 | * PARAMETERS: table_desc - table | 59 | * PARAMETERS: table_desc - Table 1 descriptor to be compared |
60 | * table_index - Index of table 2 to be compared | ||
57 | * | 61 | * |
58 | * RETURN: Status | 62 | * RETURN: TRUE if both tables are identical. |
59 | * | 63 | * |
60 | * DESCRIPTION: this function is called to verify and map table | 64 | * DESCRIPTION: This function compares a table with another table that has |
65 | * already been installed in the root table list. | ||
61 | * | 66 | * |
62 | *****************************************************************************/ | 67 | ******************************************************************************/ |
63 | acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) | 68 | |
69 | static u8 | ||
70 | acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index) | ||
64 | { | 71 | { |
65 | acpi_status status = AE_OK; | 72 | acpi_status status = AE_OK; |
73 | u8 is_identical; | ||
74 | struct acpi_table_header *table; | ||
75 | u32 table_length; | ||
76 | u8 table_flags; | ||
66 | 77 | ||
67 | ACPI_FUNCTION_TRACE(tb_verify_table); | 78 | status = |
68 | 79 | acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index], | |
69 | /* Map the table if necessary */ | 80 | &table, &table_length, &table_flags); |
70 | 81 | if (ACPI_FAILURE(status)) { | |
71 | if (!table_desc->pointer) { | 82 | return (FALSE); |
72 | if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == | ||
73 | ACPI_TABLE_ORIGIN_MAPPED) { | ||
74 | table_desc->pointer = | ||
75 | acpi_os_map_memory(table_desc->address, | ||
76 | table_desc->length); | ||
77 | } | ||
78 | if (!table_desc->pointer) { | ||
79 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
80 | } | ||
81 | } | 83 | } |
82 | 84 | ||
83 | /* Always calculate checksum, ignore bad checksum if requested */ | 85 | /* |
86 | * Check for a table match on the entire table length, | ||
87 | * not just the header. | ||
88 | */ | ||
89 | is_identical = (u8)((table_desc->length != table_length || | ||
90 | ACPI_MEMCMP(table_desc->pointer, table, | ||
91 | table_length)) ? FALSE : TRUE); | ||
84 | 92 | ||
85 | status = | 93 | /* Release the acquired table */ |
86 | acpi_tb_verify_checksum(table_desc->pointer, table_desc->length); | ||
87 | 94 | ||
88 | return_ACPI_STATUS(status); | 95 | acpi_tb_release_table(table, table_length, table_flags); |
96 | return (is_identical); | ||
89 | } | 97 | } |
90 | 98 | ||
91 | /******************************************************************************* | 99 | /******************************************************************************* |
92 | * | 100 | * |
93 | * FUNCTION: acpi_tb_add_table | 101 | * FUNCTION: acpi_tb_install_table_with_override |
94 | * | 102 | * |
95 | * PARAMETERS: table_desc - Table descriptor | 103 | * PARAMETERS: table_index - Index into root table array |
96 | * table_index - Where the table index is returned | 104 | * new_table_desc - New table descriptor to install |
105 | * override - Whether override should be performed | ||
97 | * | 106 | * |
98 | * RETURN: Status | 107 | * RETURN: None |
99 | * | 108 | * |
100 | * DESCRIPTION: This function is called to add an ACPI table. It is used to | 109 | * DESCRIPTION: Install an ACPI table into the global data structure. The |
101 | * dynamically load tables via the Load and load_table AML | 110 | * table override mechanism is called to allow the host |
102 | * operators. | 111 | * OS to replace any table before it is installed in the root |
112 | * table array. | ||
103 | * | 113 | * |
104 | ******************************************************************************/ | 114 | ******************************************************************************/ |
105 | 115 | ||
106 | acpi_status | 116 | void |
107 | acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | 117 | acpi_tb_install_table_with_override(u32 table_index, |
118 | struct acpi_table_desc *new_table_desc, | ||
119 | u8 override) | ||
108 | { | 120 | { |
109 | u32 i; | ||
110 | acpi_status status = AE_OK; | ||
111 | 121 | ||
112 | ACPI_FUNCTION_TRACE(tb_add_table); | 122 | if (table_index >= acpi_gbl_root_table_list.current_table_count) { |
113 | 123 | return; | |
114 | if (!table_desc->pointer) { | ||
115 | status = acpi_tb_verify_table(table_desc); | ||
116 | if (ACPI_FAILURE(status) || !table_desc->pointer) { | ||
117 | return_ACPI_STATUS(status); | ||
118 | } | ||
119 | } | 124 | } |
120 | 125 | ||
121 | /* | 126 | /* |
122 | * Validate the incoming table signature. | 127 | * ACPI Table Override: |
123 | * | 128 | * |
124 | * 1) Originally, we checked the table signature for "SSDT" or "PSDT". | 129 | * Before we install the table, let the host OS override it with a new |
125 | * 2) We added support for OEMx tables, signature "OEM". | 130 | * one if desired. Any table within the RSDT/XSDT can be replaced, |
126 | * 3) Valid tables were encountered with a null signature, so we just | 131 | * including the DSDT which is pointed to by the FADT. |
127 | * gave up on validating the signature, (05/2008). | ||
128 | * 4) We encountered non-AML tables such as the MADT, which caused | ||
129 | * interpreter errors and kernel faults. So now, we once again allow | ||
130 | * only "SSDT", "OEMx", and now, also a null signature. (05/2011). | ||
131 | */ | 132 | */ |
132 | if ((table_desc->pointer->signature[0] != 0x00) && | 133 | if (override) { |
133 | (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)) | 134 | acpi_tb_override_table(new_table_desc); |
134 | && (ACPI_STRNCMP(table_desc->pointer->signature, "OEM", 3))) { | ||
135 | ACPI_BIOS_ERROR((AE_INFO, | ||
136 | "Table has invalid signature [%4.4s] (0x%8.8X), " | ||
137 | "must be SSDT or OEMx", | ||
138 | acpi_ut_valid_acpi_name(table_desc->pointer-> | ||
139 | signature) ? | ||
140 | table_desc->pointer->signature : "????", | ||
141 | *(u32 *)table_desc->pointer->signature)); | ||
142 | |||
143 | return_ACPI_STATUS(AE_BAD_SIGNATURE); | ||
144 | } | 135 | } |
145 | 136 | ||
146 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 137 | acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list. |
138 | tables[table_index], | ||
139 | new_table_desc->address, | ||
140 | new_table_desc->flags, | ||
141 | new_table_desc->pointer); | ||
147 | 142 | ||
148 | /* Check if table is already registered */ | 143 | acpi_tb_print_table_header(new_table_desc->address, |
144 | new_table_desc->pointer); | ||
149 | 145 | ||
150 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { | 146 | /* Set the global integer width (based upon revision of the DSDT) */ |
151 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | ||
152 | status = | ||
153 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | ||
154 | tables[i]); | ||
155 | if (ACPI_FAILURE(status) | ||
156 | || !acpi_gbl_root_table_list.tables[i].pointer) { | ||
157 | continue; | ||
158 | } | ||
159 | } | ||
160 | 147 | ||
161 | /* | 148 | if (table_index == ACPI_TABLE_INDEX_DSDT) { |
162 | * Check for a table match on the entire table length, | 149 | acpi_ut_set_integer_width(new_table_desc->pointer->revision); |
163 | * not just the header. | ||
164 | */ | ||
165 | if (table_desc->length != | ||
166 | acpi_gbl_root_table_list.tables[i].length) { | ||
167 | continue; | ||
168 | } | ||
169 | |||
170 | if (ACPI_MEMCMP(table_desc->pointer, | ||
171 | acpi_gbl_root_table_list.tables[i].pointer, | ||
172 | acpi_gbl_root_table_list.tables[i].length)) { | ||
173 | continue; | ||
174 | } | ||
175 | |||
176 | /* | ||
177 | * Note: the current mechanism does not unregister a table if it is | ||
178 | * dynamically unloaded. The related namespace entries are deleted, | ||
179 | * but the table remains in the root table list. | ||
180 | * | ||
181 | * The assumption here is that the number of different tables that | ||
182 | * will be loaded is actually small, and there is minimal overhead | ||
183 | * in just keeping the table in case it is needed again. | ||
184 | * | ||
185 | * If this assumption changes in the future (perhaps on large | ||
186 | * machines with many table load/unload operations), tables will | ||
187 | * need to be unregistered when they are unloaded, and slots in the | ||
188 | * root table list should be reused when empty. | ||
189 | */ | ||
190 | |||
191 | /* | ||
192 | * Table is already registered. | ||
193 | * We can delete the table that was passed as a parameter. | ||
194 | */ | ||
195 | acpi_tb_delete_table(table_desc); | ||
196 | *table_index = i; | ||
197 | |||
198 | if (acpi_gbl_root_table_list.tables[i]. | ||
199 | flags & ACPI_TABLE_IS_LOADED) { | ||
200 | |||
201 | /* Table is still loaded, this is an error */ | ||
202 | |||
203 | status = AE_ALREADY_EXISTS; | ||
204 | goto release; | ||
205 | } else { | ||
206 | /* Table was unloaded, allow it to be reloaded */ | ||
207 | |||
208 | table_desc->pointer = | ||
209 | acpi_gbl_root_table_list.tables[i].pointer; | ||
210 | table_desc->address = | ||
211 | acpi_gbl_root_table_list.tables[i].address; | ||
212 | status = AE_OK; | ||
213 | goto print_header; | ||
214 | } | ||
215 | } | 150 | } |
216 | |||
217 | /* | ||
218 | * ACPI Table Override: | ||
219 | * Allow the host to override dynamically loaded tables. | ||
220 | * NOTE: the table is fully mapped at this point, and the mapping will | ||
221 | * be deleted by tb_table_override if the table is actually overridden. | ||
222 | */ | ||
223 | (void)acpi_tb_table_override(table_desc->pointer, table_desc); | ||
224 | |||
225 | /* Add the table to the global root table list */ | ||
226 | |||
227 | status = acpi_tb_store_table(table_desc->address, table_desc->pointer, | ||
228 | table_desc->length, table_desc->flags, | ||
229 | table_index); | ||
230 | if (ACPI_FAILURE(status)) { | ||
231 | goto release; | ||
232 | } | ||
233 | |||
234 | print_header: | ||
235 | acpi_tb_print_table_header(table_desc->address, table_desc->pointer); | ||
236 | |||
237 | release: | ||
238 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
239 | return_ACPI_STATUS(status); | ||
240 | } | 151 | } |
241 | 152 | ||
242 | /******************************************************************************* | 153 | /******************************************************************************* |
243 | * | 154 | * |
244 | * FUNCTION: acpi_tb_table_override | 155 | * FUNCTION: acpi_tb_install_fixed_table |
245 | * | 156 | * |
246 | * PARAMETERS: table_header - Header for the original table | 157 | * PARAMETERS: address - Physical address of DSDT or FACS |
247 | * table_desc - Table descriptor initialized for the | 158 | * signature - Table signature, NULL if no need to |
248 | * original table. May or may not be mapped. | 159 | * match |
160 | * table_index - Index into root table array | ||
249 | * | 161 | * |
250 | * RETURN: Pointer to the entire new table. NULL if table not overridden. | 162 | * RETURN: Status |
251 | * If overridden, installs the new table within the input table | ||
252 | * descriptor. | ||
253 | * | 163 | * |
254 | * DESCRIPTION: Attempt table override by calling the OSL override functions. | 164 | * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data |
255 | * Note: If the table is overridden, then the entire new table | 165 | * structure. |
256 | * is mapped and returned by this function. | ||
257 | * | 166 | * |
258 | ******************************************************************************/ | 167 | ******************************************************************************/ |
259 | 168 | ||
260 | struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header | 169 | acpi_status |
261 | *table_header, | 170 | acpi_tb_install_fixed_table(acpi_physical_address address, |
262 | struct acpi_table_desc | 171 | char *signature, u32 table_index) |
263 | *table_desc) | ||
264 | { | 172 | { |
173 | struct acpi_table_desc new_table_desc; | ||
265 | acpi_status status; | 174 | acpi_status status; |
266 | struct acpi_table_header *new_table = NULL; | ||
267 | acpi_physical_address new_address = 0; | ||
268 | u32 new_table_length = 0; | ||
269 | u8 new_flags; | ||
270 | char *override_type; | ||
271 | 175 | ||
272 | /* (1) Attempt logical override (returns a logical address) */ | 176 | ACPI_FUNCTION_TRACE(tb_install_fixed_table); |
273 | 177 | ||
274 | status = acpi_os_table_override(table_header, &new_table); | 178 | if (!address) { |
275 | if (ACPI_SUCCESS(status) && new_table) { | 179 | ACPI_ERROR((AE_INFO, |
276 | new_address = ACPI_PTR_TO_PHYSADDR(new_table); | 180 | "Null physical address for ACPI table [%s]", |
277 | new_table_length = new_table->length; | 181 | signature)); |
278 | new_flags = ACPI_TABLE_ORIGIN_OVERRIDE; | 182 | return (AE_NO_MEMORY); |
279 | override_type = "Logical"; | ||
280 | goto finish_override; | ||
281 | } | 183 | } |
282 | 184 | ||
283 | /* (2) Attempt physical override (returns a physical address) */ | 185 | /* Fill a table descriptor for validation */ |
284 | 186 | ||
285 | status = acpi_os_physical_table_override(table_header, | 187 | status = acpi_tb_acquire_temp_table(&new_table_desc, address, |
286 | &new_address, | 188 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); |
287 | &new_table_length); | 189 | if (ACPI_FAILURE(status)) { |
288 | if (ACPI_SUCCESS(status) && new_address && new_table_length) { | 190 | ACPI_ERROR((AE_INFO, "Could not acquire table length at %p", |
289 | 191 | ACPI_CAST_PTR(void, address))); | |
290 | /* Map the entire new table */ | 192 | return_ACPI_STATUS(status); |
291 | |||
292 | new_table = acpi_os_map_memory(new_address, new_table_length); | ||
293 | if (!new_table) { | ||
294 | ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, | ||
295 | "%4.4s " ACPI_PRINTF_UINT | ||
296 | " Attempted physical table override failed", | ||
297 | table_header->signature, | ||
298 | ACPI_FORMAT_TO_UINT(table_desc-> | ||
299 | address))); | ||
300 | return (NULL); | ||
301 | } | ||
302 | |||
303 | override_type = "Physical"; | ||
304 | new_flags = ACPI_TABLE_ORIGIN_MAPPED; | ||
305 | goto finish_override; | ||
306 | } | 193 | } |
307 | 194 | ||
308 | return (NULL); /* There was no override */ | 195 | /* Validate and verify a table before installation */ |
309 | |||
310 | finish_override: | ||
311 | |||
312 | ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT | ||
313 | " %s table override, new table: " ACPI_PRINTF_UINT, | ||
314 | table_header->signature, | ||
315 | ACPI_FORMAT_TO_UINT(table_desc->address), | ||
316 | override_type, ACPI_FORMAT_TO_UINT(new_table))); | ||
317 | 196 | ||
318 | /* We can now unmap/delete the original table (if fully mapped) */ | 197 | status = acpi_tb_verify_temp_table(&new_table_desc, signature); |
198 | if (ACPI_FAILURE(status)) { | ||
199 | goto release_and_exit; | ||
200 | } | ||
319 | 201 | ||
320 | acpi_tb_delete_table(table_desc); | 202 | acpi_tb_install_table_with_override(table_index, &new_table_desc, TRUE); |
321 | 203 | ||
322 | /* Setup descriptor for the new table */ | 204 | release_and_exit: |
323 | 205 | ||
324 | table_desc->address = new_address; | 206 | /* Release the temporary table descriptor */ |
325 | table_desc->pointer = new_table; | ||
326 | table_desc->length = new_table_length; | ||
327 | table_desc->flags = new_flags; | ||
328 | 207 | ||
329 | return (new_table); | 208 | acpi_tb_release_temp_table(&new_table_desc); |
209 | return_ACPI_STATUS(status); | ||
330 | } | 210 | } |
331 | 211 | ||
332 | /******************************************************************************* | 212 | /******************************************************************************* |
333 | * | 213 | * |
334 | * FUNCTION: acpi_tb_resize_root_table_list | 214 | * FUNCTION: acpi_tb_install_standard_table |
335 | * | 215 | * |
336 | * PARAMETERS: None | 216 | * PARAMETERS: address - Address of the table (might be a virtual |
217 | * address depending on the table_flags) | ||
218 | * flags - Flags for the table | ||
219 | * reload - Whether reload should be performed | ||
220 | * override - Whether override should be performed | ||
221 | * table_index - Where the table index is returned | ||
337 | * | 222 | * |
338 | * RETURN: Status | 223 | * RETURN: Status |
339 | * | 224 | * |
340 | * DESCRIPTION: Expand the size of global table array | 225 | * DESCRIPTION: This function is called to install an ACPI table that is |
226 | * neither DSDT nor FACS (a "standard" table.) | ||
227 | * When this function is called by "Load" or "LoadTable" opcodes, | ||
228 | * or by acpi_load_table() API, the "Reload" parameter is set. | ||
229 | * After sucessfully returning from this function, table is | ||
230 | * "INSTALLED" but not "VALIDATED". | ||
341 | * | 231 | * |
342 | ******************************************************************************/ | 232 | ******************************************************************************/ |
343 | 233 | ||
344 | acpi_status acpi_tb_resize_root_table_list(void) | 234 | acpi_status |
235 | acpi_tb_install_standard_table(acpi_physical_address address, | ||
236 | u8 flags, | ||
237 | u8 reload, u8 override, u32 *table_index) | ||
345 | { | 238 | { |
346 | struct acpi_table_desc *tables; | 239 | u32 i; |
347 | u32 table_count; | 240 | acpi_status status = AE_OK; |
348 | 241 | struct acpi_table_desc new_table_desc; | |
349 | ACPI_FUNCTION_TRACE(tb_resize_root_table_list); | ||
350 | |||
351 | /* allow_resize flag is a parameter to acpi_initialize_tables */ | ||
352 | 242 | ||
353 | if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { | 243 | ACPI_FUNCTION_TRACE(tb_install_standard_table); |
354 | ACPI_ERROR((AE_INFO, | ||
355 | "Resize of Root Table Array is not allowed")); | ||
356 | return_ACPI_STATUS(AE_SUPPORT); | ||
357 | } | ||
358 | 244 | ||
359 | /* Increase the Table Array size */ | 245 | /* Acquire a temporary table descriptor for validation */ |
360 | 246 | ||
361 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | 247 | status = acpi_tb_acquire_temp_table(&new_table_desc, address, flags); |
362 | table_count = acpi_gbl_root_table_list.max_table_count; | 248 | if (ACPI_FAILURE(status)) { |
363 | } else { | 249 | ACPI_ERROR((AE_INFO, "Could not acquire table length at %p", |
364 | table_count = acpi_gbl_root_table_list.current_table_count; | 250 | ACPI_CAST_PTR(void, address))); |
251 | return_ACPI_STATUS(status); | ||
365 | } | 252 | } |
366 | 253 | ||
367 | tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count + | 254 | /* |
368 | ACPI_ROOT_TABLE_SIZE_INCREMENT) * | 255 | * Optionally do not load any SSDTs from the RSDT/XSDT. This can |
369 | sizeof(struct acpi_table_desc)); | 256 | * be useful for debugging ACPI problems on some machines. |
370 | if (!tables) { | 257 | */ |
371 | ACPI_ERROR((AE_INFO, | 258 | if (!reload && |
372 | "Could not allocate new root table array")); | 259 | acpi_gbl_disable_ssdt_table_install && |
373 | return_ACPI_STATUS(AE_NO_MEMORY); | 260 | ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) { |
261 | ACPI_INFO((AE_INFO, "Ignoring installation of %4.4s at %p", | ||
262 | new_table_desc.signature.ascii, ACPI_CAST_PTR(void, | ||
263 | address))); | ||
264 | goto release_and_exit; | ||
374 | } | 265 | } |
375 | 266 | ||
376 | /* Copy and free the previous table array */ | 267 | /* Validate and verify a table before installation */ |
377 | |||
378 | if (acpi_gbl_root_table_list.tables) { | ||
379 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, | ||
380 | (acpi_size) table_count * | ||
381 | sizeof(struct acpi_table_desc)); | ||
382 | 268 | ||
383 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | 269 | status = acpi_tb_verify_temp_table(&new_table_desc, NULL); |
384 | ACPI_FREE(acpi_gbl_root_table_list.tables); | 270 | if (ACPI_FAILURE(status)) { |
385 | } | 271 | goto release_and_exit; |
386 | } | 272 | } |
387 | 273 | ||
388 | acpi_gbl_root_table_list.tables = tables; | 274 | if (reload) { |
389 | acpi_gbl_root_table_list.max_table_count = | 275 | /* |
390 | table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT; | 276 | * Validate the incoming table signature. |
391 | acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED; | 277 | * |
392 | 278 | * 1) Originally, we checked the table signature for "SSDT" or "PSDT". | |
393 | return_ACPI_STATUS(AE_OK); | 279 | * 2) We added support for OEMx tables, signature "OEM". |
394 | } | 280 | * 3) Valid tables were encountered with a null signature, so we just |
395 | 281 | * gave up on validating the signature, (05/2008). | |
396 | /******************************************************************************* | 282 | * 4) We encountered non-AML tables such as the MADT, which caused |
397 | * | 283 | * interpreter errors and kernel faults. So now, we once again allow |
398 | * FUNCTION: acpi_tb_store_table | 284 | * only "SSDT", "OEMx", and now, also a null signature. (05/2011). |
399 | * | 285 | */ |
400 | * PARAMETERS: address - Table address | 286 | if ((new_table_desc.signature.ascii[0] != 0x00) && |
401 | * table - Table header | 287 | (!ACPI_COMPARE_NAME |
402 | * length - Table length | 288 | (&new_table_desc.signature, ACPI_SIG_SSDT)) |
403 | * flags - flags | 289 | && (ACPI_STRNCMP(new_table_desc.signature.ascii, "OEM", 3))) |
404 | * | 290 | { |
405 | * RETURN: Status and table index. | 291 | ACPI_BIOS_ERROR((AE_INFO, |
406 | * | 292 | "Table has invalid signature [%4.4s] (0x%8.8X), " |
407 | * DESCRIPTION: Add an ACPI table to the global table list | 293 | "must be SSDT or OEMx", |
408 | * | 294 | acpi_ut_valid_acpi_name(new_table_desc. |
409 | ******************************************************************************/ | 295 | signature. |
296 | ascii) ? | ||
297 | new_table_desc.signature. | ||
298 | ascii : "????", | ||
299 | new_table_desc.signature.integer)); | ||
300 | |||
301 | status = AE_BAD_SIGNATURE; | ||
302 | goto release_and_exit; | ||
303 | } | ||
410 | 304 | ||
411 | acpi_status | 305 | /* Check if table is already registered */ |
412 | acpi_tb_store_table(acpi_physical_address address, | ||
413 | struct acpi_table_header *table, | ||
414 | u32 length, u8 flags, u32 *table_index) | ||
415 | { | ||
416 | acpi_status status; | ||
417 | struct acpi_table_desc *new_table; | ||
418 | 306 | ||
419 | /* Ensure that there is room for the table in the Root Table List */ | 307 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; |
308 | ++i) { | ||
309 | /* | ||
310 | * Check for a table match on the entire table length, | ||
311 | * not just the header. | ||
312 | */ | ||
313 | if (!acpi_tb_compare_tables(&new_table_desc, i)) { | ||
314 | continue; | ||
315 | } | ||
420 | 316 | ||
421 | if (acpi_gbl_root_table_list.current_table_count >= | 317 | /* |
422 | acpi_gbl_root_table_list.max_table_count) { | 318 | * Note: the current mechanism does not unregister a table if it is |
423 | status = acpi_tb_resize_root_table_list(); | 319 | * dynamically unloaded. The related namespace entries are deleted, |
424 | if (ACPI_FAILURE(status)) { | 320 | * but the table remains in the root table list. |
425 | return (status); | 321 | * |
322 | * The assumption here is that the number of different tables that | ||
323 | * will be loaded is actually small, and there is minimal overhead | ||
324 | * in just keeping the table in case it is needed again. | ||
325 | * | ||
326 | * If this assumption changes in the future (perhaps on large | ||
327 | * machines with many table load/unload operations), tables will | ||
328 | * need to be unregistered when they are unloaded, and slots in the | ||
329 | * root table list should be reused when empty. | ||
330 | */ | ||
331 | if (acpi_gbl_root_table_list.tables[i]. | ||
332 | flags & ACPI_TABLE_IS_LOADED) { | ||
333 | |||
334 | /* Table is still loaded, this is an error */ | ||
335 | |||
336 | status = AE_ALREADY_EXISTS; | ||
337 | goto release_and_exit; | ||
338 | } else { | ||
339 | /* | ||
340 | * Table was unloaded, allow it to be reloaded. | ||
341 | * As we are going to return AE_OK to the caller, we should | ||
342 | * take the responsibility of freeing the input descriptor. | ||
343 | * Refill the input descriptor to ensure | ||
344 | * acpi_tb_install_table_with_override() can be called again to | ||
345 | * indicate the re-installation. | ||
346 | */ | ||
347 | acpi_tb_uninstall_table(&new_table_desc); | ||
348 | *table_index = i; | ||
349 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
350 | return_ACPI_STATUS(AE_OK); | ||
351 | } | ||
426 | } | 352 | } |
427 | } | 353 | } |
428 | 354 | ||
429 | new_table = | 355 | /* Add the table to the global root table list */ |
430 | &acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list. | ||
431 | current_table_count]; | ||
432 | |||
433 | /* Initialize added table */ | ||
434 | |||
435 | new_table->address = address; | ||
436 | new_table->pointer = table; | ||
437 | new_table->length = length; | ||
438 | new_table->owner_id = 0; | ||
439 | new_table->flags = flags; | ||
440 | |||
441 | ACPI_MOVE_32_TO_32(&new_table->signature, table->signature); | ||
442 | |||
443 | *table_index = acpi_gbl_root_table_list.current_table_count; | ||
444 | acpi_gbl_root_table_list.current_table_count++; | ||
445 | return (AE_OK); | ||
446 | } | ||
447 | |||
448 | /******************************************************************************* | ||
449 | * | ||
450 | * FUNCTION: acpi_tb_delete_table | ||
451 | * | ||
452 | * PARAMETERS: table_index - Table index | ||
453 | * | ||
454 | * RETURN: None | ||
455 | * | ||
456 | * DESCRIPTION: Delete one internal ACPI table | ||
457 | * | ||
458 | ******************************************************************************/ | ||
459 | 356 | ||
460 | void acpi_tb_delete_table(struct acpi_table_desc *table_desc) | 357 | status = acpi_tb_get_next_root_index(&i); |
461 | { | 358 | if (ACPI_FAILURE(status)) { |
462 | /* Table must be mapped or allocated */ | 359 | goto release_and_exit; |
463 | if (!table_desc->pointer) { | ||
464 | return; | ||
465 | } | 360 | } |
466 | switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { | ||
467 | case ACPI_TABLE_ORIGIN_MAPPED: | ||
468 | |||
469 | acpi_os_unmap_memory(table_desc->pointer, table_desc->length); | ||
470 | break; | ||
471 | |||
472 | case ACPI_TABLE_ORIGIN_ALLOCATED: | ||
473 | 361 | ||
474 | ACPI_FREE(table_desc->pointer); | 362 | *table_index = i; |
475 | break; | 363 | acpi_tb_install_table_with_override(i, &new_table_desc, override); |
476 | 364 | ||
477 | /* Not mapped or allocated, there is nothing we can do */ | 365 | release_and_exit: |
478 | 366 | ||
479 | default: | 367 | /* Release the temporary table descriptor */ |
480 | 368 | ||
481 | return; | 369 | acpi_tb_release_temp_table(&new_table_desc); |
482 | } | 370 | return_ACPI_STATUS(status); |
483 | |||
484 | table_desc->pointer = NULL; | ||
485 | } | 371 | } |
486 | 372 | ||
487 | /******************************************************************************* | 373 | /******************************************************************************* |
488 | * | 374 | * |
489 | * FUNCTION: acpi_tb_terminate | 375 | * FUNCTION: acpi_tb_override_table |
490 | * | 376 | * |
491 | * PARAMETERS: None | 377 | * PARAMETERS: old_table_desc - Validated table descriptor to be |
378 | * overridden | ||
492 | * | 379 | * |
493 | * RETURN: None | 380 | * RETURN: None |
494 | * | 381 | * |
495 | * DESCRIPTION: Delete all internal ACPI tables | 382 | * DESCRIPTION: Attempt table override by calling the OSL override functions. |
383 | * Note: If the table is overridden, then the entire new table | ||
384 | * is acquired and returned by this function. | ||
385 | * Before/after invocation, the table descriptor is in a state | ||
386 | * that is "VALIDATED". | ||
496 | * | 387 | * |
497 | ******************************************************************************/ | 388 | ******************************************************************************/ |
498 | 389 | ||
499 | void acpi_tb_terminate(void) | 390 | void acpi_tb_override_table(struct acpi_table_desc *old_table_desc) |
500 | { | 391 | { |
501 | u32 i; | 392 | acpi_status status; |
502 | 393 | char *override_type; | |
503 | ACPI_FUNCTION_TRACE(tb_terminate); | 394 | struct acpi_table_desc new_table_desc; |
504 | 395 | struct acpi_table_header *table; | |
505 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 396 | acpi_physical_address address; |
506 | 397 | u32 length; | |
507 | /* Delete the individual tables */ | ||
508 | 398 | ||
509 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { | 399 | /* (1) Attempt logical override (returns a logical address) */ |
510 | acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]); | ||
511 | } | ||
512 | 400 | ||
513 | /* | 401 | status = acpi_os_table_override(old_table_desc->pointer, &table); |
514 | * Delete the root table array if allocated locally. Array cannot be | 402 | if (ACPI_SUCCESS(status) && table) { |
515 | * mapped, so we don't need to check for that flag. | 403 | acpi_tb_acquire_temp_table(&new_table_desc, |
516 | */ | 404 | ACPI_PTR_TO_PHYSADDR(table), |
517 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | 405 | ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL); |
518 | ACPI_FREE(acpi_gbl_root_table_list.tables); | 406 | override_type = "Logical"; |
407 | goto finish_override; | ||
519 | } | 408 | } |
520 | 409 | ||
521 | acpi_gbl_root_table_list.tables = NULL; | 410 | /* (2) Attempt physical override (returns a physical address) */ |
522 | acpi_gbl_root_table_list.flags = 0; | ||
523 | acpi_gbl_root_table_list.current_table_count = 0; | ||
524 | 411 | ||
525 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); | 412 | status = acpi_os_physical_table_override(old_table_desc->pointer, |
526 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 413 | &address, &length); |
414 | if (ACPI_SUCCESS(status) && address && length) { | ||
415 | acpi_tb_acquire_temp_table(&new_table_desc, address, | ||
416 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); | ||
417 | override_type = "Physical"; | ||
418 | goto finish_override; | ||
419 | } | ||
527 | 420 | ||
528 | return_VOID; | 421 | return; /* There was no override */ |
529 | } | ||
530 | 422 | ||
531 | /******************************************************************************* | 423 | finish_override: |
532 | * | ||
533 | * FUNCTION: acpi_tb_delete_namespace_by_owner | ||
534 | * | ||
535 | * PARAMETERS: table_index - Table index | ||
536 | * | ||
537 | * RETURN: Status | ||
538 | * | ||
539 | * DESCRIPTION: Delete all namespace objects created when this table was loaded. | ||
540 | * | ||
541 | ******************************************************************************/ | ||
542 | |||
543 | acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) | ||
544 | { | ||
545 | acpi_owner_id owner_id; | ||
546 | acpi_status status; | ||
547 | 424 | ||
548 | ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner); | 425 | /* Validate and verify a table before overriding */ |
549 | 426 | ||
550 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 427 | status = acpi_tb_verify_temp_table(&new_table_desc, NULL); |
551 | if (ACPI_FAILURE(status)) { | 428 | if (ACPI_FAILURE(status)) { |
552 | return_ACPI_STATUS(status); | 429 | return; |
553 | } | 430 | } |
554 | 431 | ||
555 | if (table_index >= acpi_gbl_root_table_list.current_table_count) { | 432 | ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT |
556 | 433 | " %s table override, new table: " ACPI_PRINTF_UINT, | |
557 | /* The table index does not exist */ | 434 | old_table_desc->signature.ascii, |
558 | 435 | ACPI_FORMAT_TO_UINT(old_table_desc->address), | |
559 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 436 | override_type, ACPI_FORMAT_TO_UINT(new_table_desc.address))); |
560 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
561 | } | ||
562 | 437 | ||
563 | /* Get the owner ID for this table, used to delete namespace nodes */ | 438 | /* We can now uninstall the original table */ |
564 | 439 | ||
565 | owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id; | 440 | acpi_tb_uninstall_table(old_table_desc); |
566 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
567 | 441 | ||
568 | /* | 442 | /* |
569 | * Need to acquire the namespace writer lock to prevent interference | 443 | * Replace the original table descriptor and keep its state as |
570 | * with any concurrent namespace walks. The interpreter must be | 444 | * "VALIDATED". |
571 | * released during the deletion since the acquisition of the deletion | ||
572 | * lock may block, and also since the execution of a namespace walk | ||
573 | * must be allowed to use the interpreter. | ||
574 | */ | 445 | */ |
575 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | 446 | acpi_tb_init_table_descriptor(old_table_desc, new_table_desc.address, |
576 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); | 447 | new_table_desc.flags, |
448 | new_table_desc.pointer); | ||
449 | acpi_tb_validate_temp_table(old_table_desc); | ||
577 | 450 | ||
578 | acpi_ns_delete_namespace_by_owner(owner_id); | 451 | /* Release the temporary table descriptor */ |
579 | if (ACPI_FAILURE(status)) { | ||
580 | return_ACPI_STATUS(status); | ||
581 | } | ||
582 | 452 | ||
583 | acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); | 453 | acpi_tb_release_temp_table(&new_table_desc); |
584 | |||
585 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | ||
586 | return_ACPI_STATUS(status); | ||
587 | } | 454 | } |
588 | 455 | ||
589 | /******************************************************************************* | 456 | /******************************************************************************* |
590 | * | 457 | * |
591 | * FUNCTION: acpi_tb_allocate_owner_id | 458 | * FUNCTION: acpi_tb_store_table |
592 | * | 459 | * |
593 | * PARAMETERS: table_index - Table index | 460 | * PARAMETERS: address - Table address |
461 | * table - Table header | ||
462 | * length - Table length | ||
463 | * flags - Install flags | ||
464 | * table_index - Where the table index is returned | ||
594 | * | 465 | * |
595 | * RETURN: Status | 466 | * RETURN: Status and table index. |
596 | * | 467 | * |
597 | * DESCRIPTION: Allocates owner_id in table_desc | 468 | * DESCRIPTION: Add an ACPI table to the global table list |
598 | * | 469 | * |
599 | ******************************************************************************/ | 470 | ******************************************************************************/ |
600 | 471 | ||
601 | acpi_status acpi_tb_allocate_owner_id(u32 table_index) | 472 | acpi_status |
473 | acpi_tb_store_table(acpi_physical_address address, | ||
474 | struct acpi_table_header * table, | ||
475 | u32 length, u8 flags, u32 *table_index) | ||
602 | { | 476 | { |
603 | acpi_status status = AE_BAD_PARAMETER; | 477 | acpi_status status; |
604 | 478 | struct acpi_table_desc *table_desc; | |
605 | ACPI_FUNCTION_TRACE(tb_allocate_owner_id); | ||
606 | 479 | ||
607 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 480 | status = acpi_tb_get_next_root_index(table_index); |
608 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | 481 | if (ACPI_FAILURE(status)) { |
609 | status = acpi_ut_allocate_owner_id | 482 | return (status); |
610 | (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); | ||
611 | } | 483 | } |
612 | 484 | ||
613 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 485 | /* Initialize added table */ |
614 | return_ACPI_STATUS(status); | ||
615 | } | ||
616 | |||
617 | /******************************************************************************* | ||
618 | * | ||
619 | * FUNCTION: acpi_tb_release_owner_id | ||
620 | * | ||
621 | * PARAMETERS: table_index - Table index | ||
622 | * | ||
623 | * RETURN: Status | ||
624 | * | ||
625 | * DESCRIPTION: Releases owner_id in table_desc | ||
626 | * | ||
627 | ******************************************************************************/ | ||
628 | |||
629 | acpi_status acpi_tb_release_owner_id(u32 table_index) | ||
630 | { | ||
631 | acpi_status status = AE_BAD_PARAMETER; | ||
632 | |||
633 | ACPI_FUNCTION_TRACE(tb_release_owner_id); | ||
634 | |||
635 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
636 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
637 | acpi_ut_release_owner_id(& | ||
638 | (acpi_gbl_root_table_list. | ||
639 | tables[table_index].owner_id)); | ||
640 | status = AE_OK; | ||
641 | } | ||
642 | 486 | ||
643 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 487 | table_desc = &acpi_gbl_root_table_list.tables[*table_index]; |
644 | return_ACPI_STATUS(status); | 488 | acpi_tb_init_table_descriptor(table_desc, address, flags, table); |
489 | table_desc->pointer = table; | ||
490 | return (AE_OK); | ||
645 | } | 491 | } |
646 | 492 | ||
647 | /******************************************************************************* | 493 | /******************************************************************************* |
648 | * | 494 | * |
649 | * FUNCTION: acpi_tb_get_owner_id | 495 | * FUNCTION: acpi_tb_uninstall_table |
650 | * | 496 | * |
651 | * PARAMETERS: table_index - Table index | 497 | * PARAMETERS: table_desc - Table descriptor |
652 | * owner_id - Where the table owner_id is returned | ||
653 | * | 498 | * |
654 | * RETURN: Status | 499 | * RETURN: None |
655 | * | 500 | * |
656 | * DESCRIPTION: returns owner_id for the ACPI table | 501 | * DESCRIPTION: Delete one internal ACPI table |
657 | * | 502 | * |
658 | ******************************************************************************/ | 503 | ******************************************************************************/ |
659 | 504 | ||
660 | acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id) | 505 | void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc) |
661 | { | 506 | { |
662 | acpi_status status = AE_BAD_PARAMETER; | ||
663 | |||
664 | ACPI_FUNCTION_TRACE(tb_get_owner_id); | ||
665 | 507 | ||
666 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 508 | ACPI_FUNCTION_TRACE(tb_uninstall_table); |
667 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
668 | *owner_id = | ||
669 | acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
670 | status = AE_OK; | ||
671 | } | ||
672 | 509 | ||
673 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 510 | /* Table must be installed */ |
674 | return_ACPI_STATUS(status); | ||
675 | } | ||
676 | |||
677 | /******************************************************************************* | ||
678 | * | ||
679 | * FUNCTION: acpi_tb_is_table_loaded | ||
680 | * | ||
681 | * PARAMETERS: table_index - Table index | ||
682 | * | ||
683 | * RETURN: Table Loaded Flag | ||
684 | * | ||
685 | ******************************************************************************/ | ||
686 | 511 | ||
687 | u8 acpi_tb_is_table_loaded(u32 table_index) | 512 | if (!table_desc->address) { |
688 | { | 513 | return_VOID; |
689 | u8 is_loaded = FALSE; | ||
690 | |||
691 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
692 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
693 | is_loaded = (u8) | ||
694 | (acpi_gbl_root_table_list.tables[table_index].flags & | ||
695 | ACPI_TABLE_IS_LOADED); | ||
696 | } | 514 | } |
697 | 515 | ||
698 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 516 | acpi_tb_invalidate_table(table_desc); |
699 | return (is_loaded); | ||
700 | } | ||
701 | |||
702 | /******************************************************************************* | ||
703 | * | ||
704 | * FUNCTION: acpi_tb_set_table_loaded_flag | ||
705 | * | ||
706 | * PARAMETERS: table_index - Table index | ||
707 | * is_loaded - TRUE if table is loaded, FALSE otherwise | ||
708 | * | ||
709 | * RETURN: None | ||
710 | * | ||
711 | * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. | ||
712 | * | ||
713 | ******************************************************************************/ | ||
714 | |||
715 | void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) | ||
716 | { | ||
717 | 517 | ||
718 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 518 | if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == |
719 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | 519 | ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) { |
720 | if (is_loaded) { | 520 | ACPI_FREE(ACPI_CAST_PTR(void, table_desc->address)); |
721 | acpi_gbl_root_table_list.tables[table_index].flags |= | ||
722 | ACPI_TABLE_IS_LOADED; | ||
723 | } else { | ||
724 | acpi_gbl_root_table_list.tables[table_index].flags &= | ||
725 | ~ACPI_TABLE_IS_LOADED; | ||
726 | } | ||
727 | } | 521 | } |
728 | 522 | ||
729 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 523 | table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL); |
524 | return_VOID; | ||
730 | } | 525 | } |
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 9fb85f38de90..6b1ca9991b90 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
@@ -49,8 +49,6 @@ | |||
49 | ACPI_MODULE_NAME("tbutils") | 49 | ACPI_MODULE_NAME("tbutils") |
50 | 50 | ||
51 | /* Local prototypes */ | 51 | /* Local prototypes */ |
52 | static acpi_status acpi_tb_validate_xsdt(acpi_physical_address address); | ||
53 | |||
54 | static acpi_physical_address | 52 | static acpi_physical_address |
55 | acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); | 53 | acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); |
56 | 54 | ||
@@ -178,9 +176,13 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index) | |||
178 | } | 176 | } |
179 | 177 | ||
180 | ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length); | 178 | ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length); |
181 | acpi_tb_delete_table(table_desc); | 179 | acpi_tb_uninstall_table(table_desc); |
182 | table_desc->pointer = new_table; | 180 | |
183 | table_desc->flags = ACPI_TABLE_ORIGIN_ALLOCATED; | 181 | acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list. |
182 | tables[ACPI_TABLE_INDEX_DSDT], | ||
183 | ACPI_PTR_TO_PHYSADDR(new_table), | ||
184 | ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, | ||
185 | new_table); | ||
184 | 186 | ||
185 | ACPI_INFO((AE_INFO, | 187 | ACPI_INFO((AE_INFO, |
186 | "Forced DSDT copy: length 0x%05X copied locally, original unmapped", | 188 | "Forced DSDT copy: length 0x%05X copied locally, original unmapped", |
@@ -191,116 +193,6 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index) | |||
191 | 193 | ||
192 | /******************************************************************************* | 194 | /******************************************************************************* |
193 | * | 195 | * |
194 | * FUNCTION: acpi_tb_install_table | ||
195 | * | ||
196 | * PARAMETERS: address - Physical address of DSDT or FACS | ||
197 | * signature - Table signature, NULL if no need to | ||
198 | * match | ||
199 | * table_index - Index into root table array | ||
200 | * | ||
201 | * RETURN: None | ||
202 | * | ||
203 | * DESCRIPTION: Install an ACPI table into the global data structure. The | ||
204 | * table override mechanism is called to allow the host | ||
205 | * OS to replace any table before it is installed in the root | ||
206 | * table array. | ||
207 | * | ||
208 | ******************************************************************************/ | ||
209 | |||
210 | void | ||
211 | acpi_tb_install_table(acpi_physical_address address, | ||
212 | char *signature, u32 table_index) | ||
213 | { | ||
214 | struct acpi_table_header *table; | ||
215 | struct acpi_table_header *final_table; | ||
216 | struct acpi_table_desc *table_desc; | ||
217 | |||
218 | if (!address) { | ||
219 | ACPI_ERROR((AE_INFO, | ||
220 | "Null physical address for ACPI table [%s]", | ||
221 | signature)); | ||
222 | return; | ||
223 | } | ||
224 | |||
225 | /* Map just the table header */ | ||
226 | |||
227 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); | ||
228 | if (!table) { | ||
229 | ACPI_ERROR((AE_INFO, | ||
230 | "Could not map memory for table [%s] at %p", | ||
231 | signature, ACPI_CAST_PTR(void, address))); | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | /* If a particular signature is expected (DSDT/FACS), it must match */ | ||
236 | |||
237 | if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) { | ||
238 | ACPI_BIOS_ERROR((AE_INFO, | ||
239 | "Invalid signature 0x%X for ACPI table, expected [%s]", | ||
240 | *ACPI_CAST_PTR(u32, table->signature), | ||
241 | signature)); | ||
242 | goto unmap_and_exit; | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * Initialize the table entry. Set the pointer to NULL, since the | ||
247 | * table is not fully mapped at this time. | ||
248 | */ | ||
249 | table_desc = &acpi_gbl_root_table_list.tables[table_index]; | ||
250 | |||
251 | table_desc->address = address; | ||
252 | table_desc->pointer = NULL; | ||
253 | table_desc->length = table->length; | ||
254 | table_desc->flags = ACPI_TABLE_ORIGIN_MAPPED; | ||
255 | ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature); | ||
256 | |||
257 | /* | ||
258 | * ACPI Table Override: | ||
259 | * | ||
260 | * Before we install the table, let the host OS override it with a new | ||
261 | * one if desired. Any table within the RSDT/XSDT can be replaced, | ||
262 | * including the DSDT which is pointed to by the FADT. | ||
263 | * | ||
264 | * NOTE: If the table is overridden, then final_table will contain a | ||
265 | * mapped pointer to the full new table. If the table is not overridden, | ||
266 | * or if there has been a physical override, then the table will be | ||
267 | * fully mapped later (in verify table). In any case, we must | ||
268 | * unmap the header that was mapped above. | ||
269 | */ | ||
270 | final_table = acpi_tb_table_override(table, table_desc); | ||
271 | if (!final_table) { | ||
272 | final_table = table; /* There was no override */ | ||
273 | } | ||
274 | |||
275 | acpi_tb_print_table_header(table_desc->address, final_table); | ||
276 | |||
277 | /* Set the global integer width (based upon revision of the DSDT) */ | ||
278 | |||
279 | if (table_index == ACPI_TABLE_INDEX_DSDT) { | ||
280 | acpi_ut_set_integer_width(final_table->revision); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * If we have a physical override during this early loading of the ACPI | ||
285 | * tables, unmap the table for now. It will be mapped again later when | ||
286 | * it is actually used. This supports very early loading of ACPI tables, | ||
287 | * before virtual memory is fully initialized and running within the | ||
288 | * host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE | ||
289 | * flag set and will not be deleted below. | ||
290 | */ | ||
291 | if (final_table != table) { | ||
292 | acpi_tb_delete_table(table_desc); | ||
293 | } | ||
294 | |||
295 | unmap_and_exit: | ||
296 | |||
297 | /* Always unmap the table header that we mapped above */ | ||
298 | |||
299 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
300 | } | ||
301 | |||
302 | /******************************************************************************* | ||
303 | * | ||
304 | * FUNCTION: acpi_tb_get_root_table_entry | 196 | * FUNCTION: acpi_tb_get_root_table_entry |
305 | * | 197 | * |
306 | * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry | 198 | * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry |
@@ -357,87 +249,6 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size) | |||
357 | 249 | ||
358 | /******************************************************************************* | 250 | /******************************************************************************* |
359 | * | 251 | * |
360 | * FUNCTION: acpi_tb_validate_xsdt | ||
361 | * | ||
362 | * PARAMETERS: address - Physical address of the XSDT (from RSDP) | ||
363 | * | ||
364 | * RETURN: Status. AE_OK if the table appears to be valid. | ||
365 | * | ||
366 | * DESCRIPTION: Validate an XSDT to ensure that it is of minimum size and does | ||
367 | * not contain any NULL entries. A problem that is seen in the | ||
368 | * field is that the XSDT exists, but is actually useless because | ||
369 | * of one or more (or all) NULL entries. | ||
370 | * | ||
371 | ******************************************************************************/ | ||
372 | |||
373 | static acpi_status acpi_tb_validate_xsdt(acpi_physical_address xsdt_address) | ||
374 | { | ||
375 | struct acpi_table_header *table; | ||
376 | u8 *next_entry; | ||
377 | acpi_physical_address address; | ||
378 | u32 length; | ||
379 | u32 entry_count; | ||
380 | acpi_status status; | ||
381 | u32 i; | ||
382 | |||
383 | /* Get the XSDT length */ | ||
384 | |||
385 | table = | ||
386 | acpi_os_map_memory(xsdt_address, sizeof(struct acpi_table_header)); | ||
387 | if (!table) { | ||
388 | return (AE_NO_MEMORY); | ||
389 | } | ||
390 | |||
391 | length = table->length; | ||
392 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
393 | |||
394 | /* | ||
395 | * Minimum XSDT length is the size of the standard ACPI header | ||
396 | * plus one physical address entry | ||
397 | */ | ||
398 | if (length < (sizeof(struct acpi_table_header) + ACPI_XSDT_ENTRY_SIZE)) { | ||
399 | return (AE_INVALID_TABLE_LENGTH); | ||
400 | } | ||
401 | |||
402 | /* Map the entire XSDT */ | ||
403 | |||
404 | table = acpi_os_map_memory(xsdt_address, length); | ||
405 | if (!table) { | ||
406 | return (AE_NO_MEMORY); | ||
407 | } | ||
408 | |||
409 | /* Get the number of entries and pointer to first entry */ | ||
410 | |||
411 | status = AE_OK; | ||
412 | next_entry = ACPI_ADD_PTR(u8, table, sizeof(struct acpi_table_header)); | ||
413 | entry_count = (u32)((table->length - sizeof(struct acpi_table_header)) / | ||
414 | ACPI_XSDT_ENTRY_SIZE); | ||
415 | |||
416 | /* Validate each entry (physical address) within the XSDT */ | ||
417 | |||
418 | for (i = 0; i < entry_count; i++) { | ||
419 | address = | ||
420 | acpi_tb_get_root_table_entry(next_entry, | ||
421 | ACPI_XSDT_ENTRY_SIZE); | ||
422 | if (!address) { | ||
423 | |||
424 | /* Detected a NULL entry, XSDT is invalid */ | ||
425 | |||
426 | status = AE_NULL_ENTRY; | ||
427 | break; | ||
428 | } | ||
429 | |||
430 | next_entry += ACPI_XSDT_ENTRY_SIZE; | ||
431 | } | ||
432 | |||
433 | /* Unmap table */ | ||
434 | |||
435 | acpi_os_unmap_memory(table, length); | ||
436 | return (status); | ||
437 | } | ||
438 | |||
439 | /******************************************************************************* | ||
440 | * | ||
441 | * FUNCTION: acpi_tb_parse_root_table | 252 | * FUNCTION: acpi_tb_parse_root_table |
442 | * | 253 | * |
443 | * PARAMETERS: rsdp - Pointer to the RSDP | 254 | * PARAMETERS: rsdp - Pointer to the RSDP |
@@ -461,10 +272,10 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
461 | u32 table_count; | 272 | u32 table_count; |
462 | struct acpi_table_header *table; | 273 | struct acpi_table_header *table; |
463 | acpi_physical_address address; | 274 | acpi_physical_address address; |
464 | acpi_physical_address rsdt_address; | ||
465 | u32 length; | 275 | u32 length; |
466 | u8 *table_entry; | 276 | u8 *table_entry; |
467 | acpi_status status; | 277 | acpi_status status; |
278 | u32 table_index; | ||
468 | 279 | ||
469 | ACPI_FUNCTION_TRACE(tb_parse_root_table); | 280 | ACPI_FUNCTION_TRACE(tb_parse_root_table); |
470 | 281 | ||
@@ -489,14 +300,11 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
489 | * as per the ACPI specification. | 300 | * as per the ACPI specification. |
490 | */ | 301 | */ |
491 | address = (acpi_physical_address) rsdp->xsdt_physical_address; | 302 | address = (acpi_physical_address) rsdp->xsdt_physical_address; |
492 | rsdt_address = | ||
493 | (acpi_physical_address) rsdp->rsdt_physical_address; | ||
494 | table_entry_size = ACPI_XSDT_ENTRY_SIZE; | 303 | table_entry_size = ACPI_XSDT_ENTRY_SIZE; |
495 | } else { | 304 | } else { |
496 | /* Root table is an RSDT (32-bit physical addresses) */ | 305 | /* Root table is an RSDT (32-bit physical addresses) */ |
497 | 306 | ||
498 | address = (acpi_physical_address) rsdp->rsdt_physical_address; | 307 | address = (acpi_physical_address) rsdp->rsdt_physical_address; |
499 | rsdt_address = address; | ||
500 | table_entry_size = ACPI_RSDT_ENTRY_SIZE; | 308 | table_entry_size = ACPI_RSDT_ENTRY_SIZE; |
501 | } | 309 | } |
502 | 310 | ||
@@ -506,24 +314,6 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
506 | */ | 314 | */ |
507 | acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); | 315 | acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); |
508 | 316 | ||
509 | /* | ||
510 | * If it is present and used, validate the XSDT for access/size | ||
511 | * and ensure that all table entries are at least non-NULL | ||
512 | */ | ||
513 | if (table_entry_size == ACPI_XSDT_ENTRY_SIZE) { | ||
514 | status = acpi_tb_validate_xsdt(address); | ||
515 | if (ACPI_FAILURE(status)) { | ||
516 | ACPI_BIOS_WARNING((AE_INFO, | ||
517 | "XSDT is invalid (%s), using RSDT", | ||
518 | acpi_format_exception(status))); | ||
519 | |||
520 | /* Fall back to the RSDT */ | ||
521 | |||
522 | address = rsdt_address; | ||
523 | table_entry_size = ACPI_RSDT_ENTRY_SIZE; | ||
524 | } | ||
525 | } | ||
526 | |||
527 | /* Map the RSDT/XSDT table header to get the full table length */ | 317 | /* Map the RSDT/XSDT table header to get the full table length */ |
528 | 318 | ||
529 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); | 319 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); |
@@ -576,55 +366,36 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
576 | /* Initialize the root table array from the RSDT/XSDT */ | 366 | /* Initialize the root table array from the RSDT/XSDT */ |
577 | 367 | ||
578 | for (i = 0; i < table_count; i++) { | 368 | for (i = 0; i < table_count; i++) { |
579 | if (acpi_gbl_root_table_list.current_table_count >= | ||
580 | acpi_gbl_root_table_list.max_table_count) { | ||
581 | |||
582 | /* There is no more room in the root table array, attempt resize */ | ||
583 | |||
584 | status = acpi_tb_resize_root_table_list(); | ||
585 | if (ACPI_FAILURE(status)) { | ||
586 | ACPI_WARNING((AE_INFO, | ||
587 | "Truncating %u table entries!", | ||
588 | (unsigned) (table_count - | ||
589 | (acpi_gbl_root_table_list. | ||
590 | current_table_count - | ||
591 | 2)))); | ||
592 | break; | ||
593 | } | ||
594 | } | ||
595 | 369 | ||
596 | /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ | 370 | /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ |
597 | 371 | ||
598 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list. | 372 | address = |
599 | current_table_count].address = | ||
600 | acpi_tb_get_root_table_entry(table_entry, table_entry_size); | 373 | acpi_tb_get_root_table_entry(table_entry, table_entry_size); |
601 | 374 | ||
602 | table_entry += table_entry_size; | 375 | /* Skip NULL entries in RSDT/XSDT */ |
603 | acpi_gbl_root_table_list.current_table_count++; | ||
604 | } | ||
605 | |||
606 | /* | ||
607 | * It is not possible to map more than one entry in some environments, | ||
608 | * so unmap the root table here before mapping other tables | ||
609 | */ | ||
610 | acpi_os_unmap_memory(table, length); | ||
611 | 376 | ||
612 | /* | 377 | if (!address) { |
613 | * Complete the initialization of the root table array by examining | 378 | goto next_table; |
614 | * the header of each table | 379 | } |
615 | */ | ||
616 | for (i = 2; i < acpi_gbl_root_table_list.current_table_count; i++) { | ||
617 | acpi_tb_install_table(acpi_gbl_root_table_list.tables[i]. | ||
618 | address, NULL, i); | ||
619 | 380 | ||
620 | /* Special case for FADT - validate it then get the DSDT and FACS */ | 381 | status = acpi_tb_install_standard_table(address, |
382 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, | ||
383 | FALSE, TRUE, | ||
384 | &table_index); | ||
621 | 385 | ||
622 | if (ACPI_COMPARE_NAME | 386 | if (ACPI_SUCCESS(status) && |
623 | (&acpi_gbl_root_table_list.tables[i].signature, | 387 | ACPI_COMPARE_NAME(&acpi_gbl_root_table_list. |
624 | ACPI_SIG_FADT)) { | 388 | tables[table_index].signature, |
625 | acpi_tb_parse_fadt(i); | 389 | ACPI_SIG_FADT)) { |
390 | acpi_tb_parse_fadt(table_index); | ||
626 | } | 391 | } |
392 | |||
393 | next_table: | ||
394 | |||
395 | table_entry += table_entry_size; | ||
627 | } | 396 | } |
628 | 397 | ||
398 | acpi_os_unmap_memory(table, length); | ||
399 | |||
629 | return_ACPI_STATUS(AE_OK); | 400 | return_ACPI_STATUS(AE_OK); |
630 | } | 401 | } |
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index a1593159d9ea..6482b0ded652 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c | |||
@@ -206,8 +206,8 @@ acpi_status | |||
206 | acpi_get_table_header(char *signature, | 206 | acpi_get_table_header(char *signature, |
207 | u32 instance, struct acpi_table_header *out_table_header) | 207 | u32 instance, struct acpi_table_header *out_table_header) |
208 | { | 208 | { |
209 | u32 i; | 209 | u32 i; |
210 | u32 j; | 210 | u32 j; |
211 | struct acpi_table_header *header; | 211 | struct acpi_table_header *header; |
212 | 212 | ||
213 | /* Parameter validation */ | 213 | /* Parameter validation */ |
@@ -233,7 +233,7 @@ acpi_get_table_header(char *signature, | |||
233 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | 233 | if (!acpi_gbl_root_table_list.tables[i].pointer) { |
234 | if ((acpi_gbl_root_table_list.tables[i].flags & | 234 | if ((acpi_gbl_root_table_list.tables[i].flags & |
235 | ACPI_TABLE_ORIGIN_MASK) == | 235 | ACPI_TABLE_ORIGIN_MASK) == |
236 | ACPI_TABLE_ORIGIN_MAPPED) { | 236 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL) { |
237 | header = | 237 | header = |
238 | acpi_os_map_memory(acpi_gbl_root_table_list. | 238 | acpi_os_map_memory(acpi_gbl_root_table_list. |
239 | tables[i].address, | 239 | tables[i].address, |
@@ -321,8 +321,8 @@ acpi_get_table_with_size(char *signature, | |||
321 | u32 instance, struct acpi_table_header **out_table, | 321 | u32 instance, struct acpi_table_header **out_table, |
322 | acpi_size *tbl_size) | 322 | acpi_size *tbl_size) |
323 | { | 323 | { |
324 | u32 i; | 324 | u32 i; |
325 | u32 j; | 325 | u32 j; |
326 | acpi_status status; | 326 | acpi_status status; |
327 | 327 | ||
328 | /* Parameter validation */ | 328 | /* Parameter validation */ |
@@ -346,7 +346,7 @@ acpi_get_table_with_size(char *signature, | |||
346 | } | 346 | } |
347 | 347 | ||
348 | status = | 348 | status = |
349 | acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]); | 349 | acpi_tb_validate_table(&acpi_gbl_root_table_list.tables[i]); |
350 | if (ACPI_SUCCESS(status)) { | 350 | if (ACPI_SUCCESS(status)) { |
351 | *out_table = acpi_gbl_root_table_list.tables[i].pointer; | 351 | *out_table = acpi_gbl_root_table_list.tables[i].pointer; |
352 | *tbl_size = acpi_gbl_root_table_list.tables[i].length; | 352 | *tbl_size = acpi_gbl_root_table_list.tables[i].length; |
@@ -390,7 +390,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_table) | |||
390 | * | 390 | * |
391 | ******************************************************************************/ | 391 | ******************************************************************************/ |
392 | acpi_status | 392 | acpi_status |
393 | acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table) | 393 | acpi_get_table_by_index(u32 table_index, struct acpi_table_header ** table) |
394 | { | 394 | { |
395 | acpi_status status; | 395 | acpi_status status; |
396 | 396 | ||
@@ -416,8 +416,8 @@ acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table) | |||
416 | /* Table is not mapped, map it */ | 416 | /* Table is not mapped, map it */ |
417 | 417 | ||
418 | status = | 418 | status = |
419 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | 419 | acpi_tb_validate_table(&acpi_gbl_root_table_list. |
420 | tables[table_index]); | 420 | tables[table_index]); |
421 | if (ACPI_FAILURE(status)) { | 421 | if (ACPI_FAILURE(status)) { |
422 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 422 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
423 | return_ACPI_STATUS(status); | 423 | return_ACPI_STATUS(status); |
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index 0909420fc776..ab5308b81aa8 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c | |||
@@ -117,7 +117,7 @@ static acpi_status acpi_tb_load_namespace(void) | |||
117 | tables[ACPI_TABLE_INDEX_DSDT].signature), | 117 | tables[ACPI_TABLE_INDEX_DSDT].signature), |
118 | ACPI_SIG_DSDT) | 118 | ACPI_SIG_DSDT) |
119 | || | 119 | || |
120 | ACPI_FAILURE(acpi_tb_verify_table | 120 | ACPI_FAILURE(acpi_tb_validate_table |
121 | (&acpi_gbl_root_table_list. | 121 | (&acpi_gbl_root_table_list. |
122 | tables[ACPI_TABLE_INDEX_DSDT]))) { | 122 | tables[ACPI_TABLE_INDEX_DSDT]))) { |
123 | status = AE_NO_ACPI_TABLES; | 123 | status = AE_NO_ACPI_TABLES; |
@@ -128,7 +128,7 @@ static acpi_status acpi_tb_load_namespace(void) | |||
128 | * Save the DSDT pointer for simple access. This is the mapped memory | 128 | * Save the DSDT pointer for simple access. This is the mapped memory |
129 | * address. We must take care here because the address of the .Tables | 129 | * address. We must take care here because the address of the .Tables |
130 | * array can change dynamically as tables are loaded at run-time. Note: | 130 | * array can change dynamically as tables are loaded at run-time. Note: |
131 | * .Pointer field is not validated until after call to acpi_tb_verify_table. | 131 | * .Pointer field is not validated until after call to acpi_tb_validate_table. |
132 | */ | 132 | */ |
133 | acpi_gbl_DSDT = | 133 | acpi_gbl_DSDT = |
134 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer; | 134 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer; |
@@ -174,24 +174,11 @@ static acpi_status acpi_tb_load_namespace(void) | |||
174 | (acpi_gbl_root_table_list.tables[i]. | 174 | (acpi_gbl_root_table_list.tables[i]. |
175 | signature), ACPI_SIG_PSDT)) | 175 | signature), ACPI_SIG_PSDT)) |
176 | || | 176 | || |
177 | ACPI_FAILURE(acpi_tb_verify_table | 177 | ACPI_FAILURE(acpi_tb_validate_table |
178 | (&acpi_gbl_root_table_list.tables[i]))) { | 178 | (&acpi_gbl_root_table_list.tables[i]))) { |
179 | continue; | 179 | continue; |
180 | } | 180 | } |
181 | 181 | ||
182 | /* | ||
183 | * Optionally do not load any SSDTs from the RSDT/XSDT. This can | ||
184 | * be useful for debugging ACPI problems on some machines. | ||
185 | */ | ||
186 | if (acpi_gbl_disable_ssdt_table_load) { | ||
187 | ACPI_INFO((AE_INFO, "Ignoring %4.4s at %p", | ||
188 | acpi_gbl_root_table_list.tables[i].signature. | ||
189 | ascii, ACPI_CAST_PTR(void, | ||
190 | acpi_gbl_root_table_list. | ||
191 | tables[i].address))); | ||
192 | continue; | ||
193 | } | ||
194 | |||
195 | /* Ignore errors while loading tables, get as many as possible */ | 182 | /* Ignore errors while loading tables, get as many as possible */ |
196 | 183 | ||
197 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 184 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
@@ -208,6 +195,45 @@ unlock_and_exit: | |||
208 | 195 | ||
209 | /******************************************************************************* | 196 | /******************************************************************************* |
210 | * | 197 | * |
198 | * FUNCTION: acpi_install_table | ||
199 | * | ||
200 | * PARAMETERS: address - Address of the ACPI table to be installed. | ||
201 | * physical - Whether the address is a physical table | ||
202 | * address or not | ||
203 | * | ||
204 | * RETURN: Status | ||
205 | * | ||
206 | * DESCRIPTION: Dynamically install an ACPI table. | ||
207 | * Note: This function should only be invoked after | ||
208 | * acpi_initialize_tables() and before acpi_load_tables(). | ||
209 | * | ||
210 | ******************************************************************************/ | ||
211 | |||
212 | acpi_status __init | ||
213 | acpi_install_table(acpi_physical_address address, u8 physical) | ||
214 | { | ||
215 | acpi_status status; | ||
216 | u8 flags; | ||
217 | u32 table_index; | ||
218 | |||
219 | ACPI_FUNCTION_TRACE(acpi_install_table); | ||
220 | |||
221 | if (physical) { | ||
222 | flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL; | ||
223 | } else { | ||
224 | flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL; | ||
225 | } | ||
226 | |||
227 | status = acpi_tb_install_standard_table(address, flags, | ||
228 | FALSE, FALSE, &table_index); | ||
229 | |||
230 | return_ACPI_STATUS(status); | ||
231 | } | ||
232 | |||
233 | ACPI_EXPORT_SYMBOL_INIT(acpi_install_table) | ||
234 | |||
235 | /******************************************************************************* | ||
236 | * | ||
211 | * FUNCTION: acpi_load_table | 237 | * FUNCTION: acpi_load_table |
212 | * | 238 | * |
213 | * PARAMETERS: table - Pointer to a buffer containing the ACPI | 239 | * PARAMETERS: table - Pointer to a buffer containing the ACPI |
@@ -222,11 +248,9 @@ unlock_and_exit: | |||
222 | * to ensure that the table is not deleted or unmapped. | 248 | * to ensure that the table is not deleted or unmapped. |
223 | * | 249 | * |
224 | ******************************************************************************/ | 250 | ******************************************************************************/ |
225 | |||
226 | acpi_status acpi_load_table(struct acpi_table_header *table) | 251 | acpi_status acpi_load_table(struct acpi_table_header *table) |
227 | { | 252 | { |
228 | acpi_status status; | 253 | acpi_status status; |
229 | struct acpi_table_desc table_desc; | ||
230 | u32 table_index; | 254 | u32 table_index; |
231 | 255 | ||
232 | ACPI_FUNCTION_TRACE(acpi_load_table); | 256 | ACPI_FUNCTION_TRACE(acpi_load_table); |
@@ -237,14 +261,6 @@ acpi_status acpi_load_table(struct acpi_table_header *table) | |||
237 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 261 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
238 | } | 262 | } |
239 | 263 | ||
240 | /* Init local table descriptor */ | ||
241 | |||
242 | ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); | ||
243 | table_desc.address = ACPI_PTR_TO_PHYSADDR(table); | ||
244 | table_desc.pointer = table; | ||
245 | table_desc.length = table->length; | ||
246 | table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN; | ||
247 | |||
248 | /* Must acquire the interpreter lock during this operation */ | 264 | /* Must acquire the interpreter lock during this operation */ |
249 | 265 | ||
250 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | 266 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); |
@@ -255,7 +271,24 @@ acpi_status acpi_load_table(struct acpi_table_header *table) | |||
255 | /* Install the table and load it into the namespace */ | 271 | /* Install the table and load it into the namespace */ |
256 | 272 | ||
257 | ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:")); | 273 | ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:")); |
258 | status = acpi_tb_add_table(&table_desc, &table_index); | 274 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
275 | |||
276 | status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table), | ||
277 | ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, | ||
278 | TRUE, FALSE, &table_index); | ||
279 | |||
280 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
281 | if (ACPI_FAILURE(status)) { | ||
282 | goto unlock_and_exit; | ||
283 | } | ||
284 | |||
285 | /* | ||
286 | * Note: Now table is "INSTALLED", it must be validated before | ||
287 | * using. | ||
288 | */ | ||
289 | status = | ||
290 | acpi_tb_validate_table(&acpi_gbl_root_table_list. | ||
291 | tables[table_index]); | ||
259 | if (ACPI_FAILURE(status)) { | 292 | if (ACPI_FAILURE(status)) { |
260 | goto unlock_and_exit; | 293 | goto unlock_and_exit; |
261 | } | 294 | } |
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index fbfa9eca011f..90ec37c473c6 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c | |||
@@ -462,7 +462,7 @@ char *acpi_ut_get_mutex_name(u32 mutex_id) | |||
462 | 462 | ||
463 | /* Names for Notify() values, used for debug output */ | 463 | /* Names for Notify() values, used for debug output */ |
464 | 464 | ||
465 | static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = { | 465 | static const char *acpi_gbl_generic_notify[ACPI_NOTIFY_MAX + 1] = { |
466 | /* 00 */ "Bus Check", | 466 | /* 00 */ "Bus Check", |
467 | /* 01 */ "Device Check", | 467 | /* 01 */ "Device Check", |
468 | /* 02 */ "Device Wake", | 468 | /* 02 */ "Device Wake", |
@@ -473,23 +473,75 @@ static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = { | |||
473 | /* 07 */ "Power Fault", | 473 | /* 07 */ "Power Fault", |
474 | /* 08 */ "Capabilities Check", | 474 | /* 08 */ "Capabilities Check", |
475 | /* 09 */ "Device PLD Check", | 475 | /* 09 */ "Device PLD Check", |
476 | /* 10 */ "Reserved", | 476 | /* 0A */ "Reserved", |
477 | /* 11 */ "System Locality Update", | 477 | /* 0B */ "System Locality Update", |
478 | /* 12 */ "Shutdown Request" | 478 | /* 0C */ "Shutdown Request" |
479 | }; | 479 | }; |
480 | 480 | ||
481 | const char *acpi_ut_get_notify_name(u32 notify_value) | 481 | static const char *acpi_gbl_device_notify[4] = { |
482 | /* 80 */ "Status Change", | ||
483 | /* 81 */ "Information Change", | ||
484 | /* 82 */ "Device-Specific Change", | ||
485 | /* 83 */ "Device-Specific Change" | ||
486 | }; | ||
487 | |||
488 | static const char *acpi_gbl_processor_notify[4] = { | ||
489 | /* 80 */ "Performance Capability Change", | ||
490 | /* 81 */ "C-State Change", | ||
491 | /* 82 */ "Throttling Capability Change", | ||
492 | /* 83 */ "Device-Specific Change" | ||
493 | }; | ||
494 | |||
495 | static const char *acpi_gbl_thermal_notify[4] = { | ||
496 | /* 80 */ "Thermal Status Change", | ||
497 | /* 81 */ "Thermal Trip Point Change", | ||
498 | /* 82 */ "Thermal Device List Change", | ||
499 | /* 83 */ "Thermal Relationship Change" | ||
500 | }; | ||
501 | |||
502 | const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type) | ||
482 | { | 503 | { |
483 | 504 | ||
505 | /* 00 - 0C are common to all object types */ | ||
506 | |||
484 | if (notify_value <= ACPI_NOTIFY_MAX) { | 507 | if (notify_value <= ACPI_NOTIFY_MAX) { |
485 | return (acpi_gbl_notify_value_names[notify_value]); | 508 | return (acpi_gbl_generic_notify[notify_value]); |
486 | } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) { | 509 | } |
510 | |||
511 | /* 0D - 7F are reserved */ | ||
512 | |||
513 | if (notify_value <= ACPI_MAX_SYS_NOTIFY) { | ||
487 | return ("Reserved"); | 514 | return ("Reserved"); |
488 | } else if (notify_value <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) { | ||
489 | return ("Device Specific"); | ||
490 | } else { | ||
491 | return ("Hardware Specific"); | ||
492 | } | 515 | } |
516 | |||
517 | /* 80 - 83 are per-object-type */ | ||
518 | |||
519 | if (notify_value <= 0x83) { | ||
520 | switch (type) { | ||
521 | case ACPI_TYPE_ANY: | ||
522 | case ACPI_TYPE_DEVICE: | ||
523 | return (acpi_gbl_device_notify[notify_value - 0x80]); | ||
524 | |||
525 | case ACPI_TYPE_PROCESSOR: | ||
526 | return (acpi_gbl_processor_notify[notify_value - 0x80]); | ||
527 | |||
528 | case ACPI_TYPE_THERMAL: | ||
529 | return (acpi_gbl_thermal_notify[notify_value - 0x80]); | ||
530 | |||
531 | default: | ||
532 | return ("Target object type does not support notifies"); | ||
533 | } | ||
534 | } | ||
535 | |||
536 | /* 84 - BF are device-specific */ | ||
537 | |||
538 | if (notify_value <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) { | ||
539 | return ("Device-Specific"); | ||
540 | } | ||
541 | |||
542 | /* C0 and above are hardware-specific */ | ||
543 | |||
544 | return ("Hardware-Specific"); | ||
493 | } | 545 | } |
494 | #endif | 546 | #endif |
495 | 547 | ||
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index f3abeae9d2f8..d69be3cb3fae 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -55,28 +55,7 @@ ACPI_MODULE_NAME("utglobal") | |||
55 | * Static global variable initialization. | 55 | * Static global variable initialization. |
56 | * | 56 | * |
57 | ******************************************************************************/ | 57 | ******************************************************************************/ |
58 | /* Debug output control masks */ | ||
59 | u32 acpi_dbg_level = ACPI_DEBUG_DEFAULT; | ||
60 | |||
61 | u32 acpi_dbg_layer = 0; | ||
62 | |||
63 | /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ | ||
64 | |||
65 | struct acpi_table_fadt acpi_gbl_FADT; | ||
66 | u32 acpi_gbl_trace_flags; | ||
67 | acpi_name acpi_gbl_trace_method_name; | ||
68 | u8 acpi_gbl_system_awake_and_running; | ||
69 | u32 acpi_current_gpe_count; | ||
70 | |||
71 | /* | ||
72 | * ACPI 5.0 introduces the concept of a "reduced hardware platform", meaning | ||
73 | * that the ACPI hardware is no longer required. A flag in the FADT indicates | ||
74 | * a reduced HW machine, and that flag is duplicated here for convenience. | ||
75 | */ | ||
76 | u8 acpi_gbl_reduced_hardware; | ||
77 | |||
78 | /* Various state name strings */ | 58 | /* Various state name strings */ |
79 | |||
80 | const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { | 59 | const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { |
81 | "\\_S0_", | 60 | "\\_S0_", |
82 | "\\_S1_", | 61 | "\\_S1_", |
@@ -337,7 +316,6 @@ acpi_status acpi_ut_init_globals(void) | |||
337 | acpi_gbl_acpi_hardware_present = TRUE; | 316 | acpi_gbl_acpi_hardware_present = TRUE; |
338 | acpi_gbl_last_owner_id_index = 0; | 317 | acpi_gbl_last_owner_id_index = 0; |
339 | acpi_gbl_next_owner_id_offset = 0; | 318 | acpi_gbl_next_owner_id_offset = 0; |
340 | acpi_gbl_trace_method_name = 0; | ||
341 | acpi_gbl_trace_dbg_level = 0; | 319 | acpi_gbl_trace_dbg_level = 0; |
342 | acpi_gbl_trace_dbg_layer = 0; | 320 | acpi_gbl_trace_dbg_layer = 0; |
343 | acpi_gbl_debugger_configuration = DEBUGGER_THREADING; | 321 | acpi_gbl_debugger_configuration = DEBUGGER_THREADING; |
@@ -377,9 +355,7 @@ acpi_status acpi_ut_init_globals(void) | |||
377 | acpi_gbl_disable_mem_tracking = FALSE; | 355 | acpi_gbl_disable_mem_tracking = FALSE; |
378 | #endif | 356 | #endif |
379 | 357 | ||
380 | #ifdef ACPI_DEBUGGER | 358 | ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE); |
381 | acpi_gbl_db_terminate_threads = FALSE; | ||
382 | #endif | ||
383 | 359 | ||
384 | return_ACPI_STATUS(AE_OK); | 360 | return_ACPI_STATUS(AE_OK); |
385 | } | 361 | } |
diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c index 77219336c7e0..6dc54b3c28b0 100644 --- a/drivers/acpi/acpica/utstring.c +++ b/drivers/acpi/acpica/utstring.c | |||
@@ -353,7 +353,7 @@ void acpi_ut_print_string(char *string, u16 max_length) | |||
353 | } | 353 | } |
354 | 354 | ||
355 | acpi_os_printf("\""); | 355 | acpi_os_printf("\""); |
356 | for (i = 0; string[i] && (i < max_length); i++) { | 356 | for (i = 0; (i < max_length) && string[i]; i++) { |
357 | 357 | ||
358 | /* Escape sequences */ | 358 | /* Escape sequences */ |
359 | 359 | ||
diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c index edd861102f1b..88ef77f3cf88 100644 --- a/drivers/acpi/acpica/utxferror.c +++ b/drivers/acpi/acpica/utxferror.c | |||
@@ -53,6 +53,7 @@ ACPI_MODULE_NAME("utxferror") | |||
53 | * This module is used for the in-kernel ACPICA as well as the ACPICA | 53 | * This module is used for the in-kernel ACPICA as well as the ACPICA |
54 | * tools/applications. | 54 | * tools/applications. |
55 | */ | 55 | */ |
56 | #ifndef ACPI_NO_ERROR_MESSAGES /* Entire module */ | ||
56 | /******************************************************************************* | 57 | /******************************************************************************* |
57 | * | 58 | * |
58 | * FUNCTION: acpi_error | 59 | * FUNCTION: acpi_error |
@@ -249,3 +250,4 @@ acpi_bios_warning(const char *module_name, | |||
249 | } | 250 | } |
250 | 251 | ||
251 | ACPI_EXPORT_SYMBOL(acpi_bios_warning) | 252 | ACPI_EXPORT_SYMBOL(acpi_bios_warning) |
253 | #endif /* ACPI_NO_ERROR_MESSAGES */ | ||
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 1be6f5564485..a095d4f858da 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c | |||
@@ -202,7 +202,7 @@ static void check_vendor_extension(u64 paddr, | |||
202 | 202 | ||
203 | if (!offset) | 203 | if (!offset) |
204 | return; | 204 | return; |
205 | v = acpi_os_map_memory(paddr + offset, sizeof(*v)); | 205 | v = acpi_os_map_iomem(paddr + offset, sizeof(*v)); |
206 | if (!v) | 206 | if (!v) |
207 | return; | 207 | return; |
208 | sbdf = v->pcie_sbdf; | 208 | sbdf = v->pcie_sbdf; |
@@ -210,7 +210,7 @@ static void check_vendor_extension(u64 paddr, | |||
210 | sbdf >> 24, (sbdf >> 16) & 0xff, | 210 | sbdf >> 24, (sbdf >> 16) & 0xff, |
211 | (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7, | 211 | (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7, |
212 | v->vendor_id, v->device_id, v->rev_id); | 212 | v->vendor_id, v->device_id, v->rev_id); |
213 | acpi_os_unmap_memory(v, sizeof(*v)); | 213 | acpi_os_unmap_iomem(v, sizeof(*v)); |
214 | } | 214 | } |
215 | 215 | ||
216 | static void *einj_get_parameter_address(void) | 216 | static void *einj_get_parameter_address(void) |
@@ -236,7 +236,7 @@ static void *einj_get_parameter_address(void) | |||
236 | if (pa_v5) { | 236 | if (pa_v5) { |
237 | struct set_error_type_with_address *v5param; | 237 | struct set_error_type_with_address *v5param; |
238 | 238 | ||
239 | v5param = acpi_os_map_memory(pa_v5, sizeof(*v5param)); | 239 | v5param = acpi_os_map_iomem(pa_v5, sizeof(*v5param)); |
240 | if (v5param) { | 240 | if (v5param) { |
241 | acpi5 = 1; | 241 | acpi5 = 1; |
242 | check_vendor_extension(pa_v5, v5param); | 242 | check_vendor_extension(pa_v5, v5param); |
@@ -246,11 +246,11 @@ static void *einj_get_parameter_address(void) | |||
246 | if (param_extension && pa_v4) { | 246 | if (param_extension && pa_v4) { |
247 | struct einj_parameter *v4param; | 247 | struct einj_parameter *v4param; |
248 | 248 | ||
249 | v4param = acpi_os_map_memory(pa_v4, sizeof(*v4param)); | 249 | v4param = acpi_os_map_iomem(pa_v4, sizeof(*v4param)); |
250 | if (!v4param) | 250 | if (!v4param) |
251 | return NULL; | 251 | return NULL; |
252 | if (v4param->reserved1 || v4param->reserved2) { | 252 | if (v4param->reserved1 || v4param->reserved2) { |
253 | acpi_os_unmap_memory(v4param, sizeof(*v4param)); | 253 | acpi_os_unmap_iomem(v4param, sizeof(*v4param)); |
254 | return NULL; | 254 | return NULL; |
255 | } | 255 | } |
256 | return v4param; | 256 | return v4param; |
@@ -794,7 +794,7 @@ err_unmap: | |||
794 | sizeof(struct set_error_type_with_address) : | 794 | sizeof(struct set_error_type_with_address) : |
795 | sizeof(struct einj_parameter); | 795 | sizeof(struct einj_parameter); |
796 | 796 | ||
797 | acpi_os_unmap_memory(einj_param, size); | 797 | acpi_os_unmap_iomem(einj_param, size); |
798 | } | 798 | } |
799 | apei_exec_post_unmap_gars(&ctx); | 799 | apei_exec_post_unmap_gars(&ctx); |
800 | err_release: | 800 | err_release: |
@@ -816,7 +816,7 @@ static void __exit einj_exit(void) | |||
816 | sizeof(struct set_error_type_with_address) : | 816 | sizeof(struct set_error_type_with_address) : |
817 | sizeof(struct einj_parameter); | 817 | sizeof(struct einj_parameter); |
818 | 818 | ||
819 | acpi_os_unmap_memory(einj_param, size); | 819 | acpi_os_unmap_iomem(einj_param, size); |
820 | } | 820 | } |
821 | einj_exec_ctx_init(&ctx); | 821 | einj_exec_ctx_init(&ctx); |
822 | apei_exec_post_unmap_gars(&ctx); | 822 | apei_exec_post_unmap_gars(&ctx); |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 6e7b2a12860d..e48fc98e71c4 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -56,6 +56,10 @@ | |||
56 | /* Battery power unit: 0 means mW, 1 means mA */ | 56 | /* Battery power unit: 0 means mW, 1 means mA */ |
57 | #define ACPI_BATTERY_POWER_UNIT_MA 1 | 57 | #define ACPI_BATTERY_POWER_UNIT_MA 1 |
58 | 58 | ||
59 | #define ACPI_BATTERY_STATE_DISCHARGING 0x1 | ||
60 | #define ACPI_BATTERY_STATE_CHARGING 0x2 | ||
61 | #define ACPI_BATTERY_STATE_CRITICAL 0x4 | ||
62 | |||
59 | #define _COMPONENT ACPI_BATTERY_COMPONENT | 63 | #define _COMPONENT ACPI_BATTERY_COMPONENT |
60 | 64 | ||
61 | ACPI_MODULE_NAME("battery"); | 65 | ACPI_MODULE_NAME("battery"); |
@@ -169,7 +173,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery); | |||
169 | 173 | ||
170 | static int acpi_battery_is_charged(struct acpi_battery *battery) | 174 | static int acpi_battery_is_charged(struct acpi_battery *battery) |
171 | { | 175 | { |
172 | /* either charging or discharging */ | 176 | /* charging, discharging or critical low */ |
173 | if (battery->state != 0) | 177 | if (battery->state != 0) |
174 | return 0; | 178 | return 0; |
175 | 179 | ||
@@ -204,9 +208,9 @@ static int acpi_battery_get_property(struct power_supply *psy, | |||
204 | return -ENODEV; | 208 | return -ENODEV; |
205 | switch (psp) { | 209 | switch (psp) { |
206 | case POWER_SUPPLY_PROP_STATUS: | 210 | case POWER_SUPPLY_PROP_STATUS: |
207 | if (battery->state & 0x01) | 211 | if (battery->state & ACPI_BATTERY_STATE_DISCHARGING) |
208 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | 212 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; |
209 | else if (battery->state & 0x02) | 213 | else if (battery->state & ACPI_BATTERY_STATE_CHARGING) |
210 | val->intval = POWER_SUPPLY_STATUS_CHARGING; | 214 | val->intval = POWER_SUPPLY_STATUS_CHARGING; |
211 | else if (acpi_battery_is_charged(battery)) | 215 | else if (acpi_battery_is_charged(battery)) |
212 | val->intval = POWER_SUPPLY_STATUS_FULL; | 216 | val->intval = POWER_SUPPLY_STATUS_FULL; |
@@ -269,6 +273,17 @@ static int acpi_battery_get_property(struct power_supply *psy, | |||
269 | else | 273 | else |
270 | val->intval = 0; | 274 | val->intval = 0; |
271 | break; | 275 | break; |
276 | case POWER_SUPPLY_PROP_CAPACITY_LEVEL: | ||
277 | if (battery->state & ACPI_BATTERY_STATE_CRITICAL) | ||
278 | val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; | ||
279 | else if (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) && | ||
280 | (battery->capacity_now <= battery->alarm)) | ||
281 | val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW; | ||
282 | else if (acpi_battery_is_charged(battery)) | ||
283 | val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL; | ||
284 | else | ||
285 | val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; | ||
286 | break; | ||
272 | case POWER_SUPPLY_PROP_MODEL_NAME: | 287 | case POWER_SUPPLY_PROP_MODEL_NAME: |
273 | val->strval = battery->model_number; | 288 | val->strval = battery->model_number; |
274 | break; | 289 | break; |
@@ -296,6 +311,7 @@ static enum power_supply_property charge_battery_props[] = { | |||
296 | POWER_SUPPLY_PROP_CHARGE_FULL, | 311 | POWER_SUPPLY_PROP_CHARGE_FULL, |
297 | POWER_SUPPLY_PROP_CHARGE_NOW, | 312 | POWER_SUPPLY_PROP_CHARGE_NOW, |
298 | POWER_SUPPLY_PROP_CAPACITY, | 313 | POWER_SUPPLY_PROP_CAPACITY, |
314 | POWER_SUPPLY_PROP_CAPACITY_LEVEL, | ||
299 | POWER_SUPPLY_PROP_MODEL_NAME, | 315 | POWER_SUPPLY_PROP_MODEL_NAME, |
300 | POWER_SUPPLY_PROP_MANUFACTURER, | 316 | POWER_SUPPLY_PROP_MANUFACTURER, |
301 | POWER_SUPPLY_PROP_SERIAL_NUMBER, | 317 | POWER_SUPPLY_PROP_SERIAL_NUMBER, |
@@ -313,6 +329,7 @@ static enum power_supply_property energy_battery_props[] = { | |||
313 | POWER_SUPPLY_PROP_ENERGY_FULL, | 329 | POWER_SUPPLY_PROP_ENERGY_FULL, |
314 | POWER_SUPPLY_PROP_ENERGY_NOW, | 330 | POWER_SUPPLY_PROP_ENERGY_NOW, |
315 | POWER_SUPPLY_PROP_CAPACITY, | 331 | POWER_SUPPLY_PROP_CAPACITY, |
332 | POWER_SUPPLY_PROP_CAPACITY_LEVEL, | ||
316 | POWER_SUPPLY_PROP_MODEL_NAME, | 333 | POWER_SUPPLY_PROP_MODEL_NAME, |
317 | POWER_SUPPLY_PROP_MANUFACTURER, | 334 | POWER_SUPPLY_PROP_MANUFACTURER, |
318 | POWER_SUPPLY_PROP_SERIAL_NUMBER, | 335 | POWER_SUPPLY_PROP_SERIAL_NUMBER, |
@@ -605,7 +622,8 @@ static int sysfs_add_battery(struct acpi_battery *battery) | |||
605 | battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; | 622 | battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; |
606 | battery->bat.get_property = acpi_battery_get_property; | 623 | battery->bat.get_property = acpi_battery_get_property; |
607 | 624 | ||
608 | result = power_supply_register(&battery->device->dev, &battery->bat); | 625 | result = power_supply_register_no_ws(&battery->device->dev, &battery->bat); |
626 | |||
609 | if (result) | 627 | if (result) |
610 | return result; | 628 | return result; |
611 | return device_create_file(battery->bat.dev, &alarm_attr); | 629 | return device_create_file(battery->bat.dev, &alarm_attr); |
@@ -696,7 +714,7 @@ static void acpi_battery_quirks(struct acpi_battery *battery) | |||
696 | } | 714 | } |
697 | } | 715 | } |
698 | 716 | ||
699 | static int acpi_battery_update(struct acpi_battery *battery) | 717 | static int acpi_battery_update(struct acpi_battery *battery, bool resume) |
700 | { | 718 | { |
701 | int result, old_present = acpi_battery_present(battery); | 719 | int result, old_present = acpi_battery_present(battery); |
702 | result = acpi_battery_get_status(battery); | 720 | result = acpi_battery_get_status(battery); |
@@ -707,6 +725,10 @@ static int acpi_battery_update(struct acpi_battery *battery) | |||
707 | battery->update_time = 0; | 725 | battery->update_time = 0; |
708 | return 0; | 726 | return 0; |
709 | } | 727 | } |
728 | |||
729 | if (resume) | ||
730 | return 0; | ||
731 | |||
710 | if (!battery->update_time || | 732 | if (!battery->update_time || |
711 | old_present != acpi_battery_present(battery)) { | 733 | old_present != acpi_battery_present(battery)) { |
712 | result = acpi_battery_get_info(battery); | 734 | result = acpi_battery_get_info(battery); |
@@ -720,7 +742,19 @@ static int acpi_battery_update(struct acpi_battery *battery) | |||
720 | return result; | 742 | return result; |
721 | } | 743 | } |
722 | result = acpi_battery_get_state(battery); | 744 | result = acpi_battery_get_state(battery); |
745 | if (result) | ||
746 | return result; | ||
723 | acpi_battery_quirks(battery); | 747 | acpi_battery_quirks(battery); |
748 | |||
749 | /* | ||
750 | * Wakeup the system if battery is critical low | ||
751 | * or lower than the alarm level | ||
752 | */ | ||
753 | if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) || | ||
754 | (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) && | ||
755 | (battery->capacity_now <= battery->alarm))) | ||
756 | pm_wakeup_event(&battery->device->dev, 0); | ||
757 | |||
724 | return result; | 758 | return result; |
725 | } | 759 | } |
726 | 760 | ||
@@ -915,7 +949,7 @@ static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = { | |||
915 | static int acpi_battery_read(int fid, struct seq_file *seq) | 949 | static int acpi_battery_read(int fid, struct seq_file *seq) |
916 | { | 950 | { |
917 | struct acpi_battery *battery = seq->private; | 951 | struct acpi_battery *battery = seq->private; |
918 | int result = acpi_battery_update(battery); | 952 | int result = acpi_battery_update(battery, false); |
919 | return acpi_print_funcs[fid](seq, result); | 953 | return acpi_print_funcs[fid](seq, result); |
920 | } | 954 | } |
921 | 955 | ||
@@ -1030,7 +1064,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event) | |||
1030 | old = battery->bat.dev; | 1064 | old = battery->bat.dev; |
1031 | if (event == ACPI_BATTERY_NOTIFY_INFO) | 1065 | if (event == ACPI_BATTERY_NOTIFY_INFO) |
1032 | acpi_battery_refresh(battery); | 1066 | acpi_battery_refresh(battery); |
1033 | acpi_battery_update(battery); | 1067 | acpi_battery_update(battery, false); |
1034 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 1068 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
1035 | dev_name(&device->dev), event, | 1069 | dev_name(&device->dev), event, |
1036 | acpi_battery_present(battery)); | 1070 | acpi_battery_present(battery)); |
@@ -1045,13 +1079,27 @@ static int battery_notify(struct notifier_block *nb, | |||
1045 | { | 1079 | { |
1046 | struct acpi_battery *battery = container_of(nb, struct acpi_battery, | 1080 | struct acpi_battery *battery = container_of(nb, struct acpi_battery, |
1047 | pm_nb); | 1081 | pm_nb); |
1082 | int result; | ||
1083 | |||
1048 | switch (mode) { | 1084 | switch (mode) { |
1049 | case PM_POST_HIBERNATION: | 1085 | case PM_POST_HIBERNATION: |
1050 | case PM_POST_SUSPEND: | 1086 | case PM_POST_SUSPEND: |
1051 | if (battery->bat.dev) { | 1087 | if (!acpi_battery_present(battery)) |
1052 | sysfs_remove_battery(battery); | 1088 | return 0; |
1053 | sysfs_add_battery(battery); | 1089 | |
1054 | } | 1090 | if (!battery->bat.dev) { |
1091 | result = acpi_battery_get_info(battery); | ||
1092 | if (result) | ||
1093 | return result; | ||
1094 | |||
1095 | result = sysfs_add_battery(battery); | ||
1096 | if (result) | ||
1097 | return result; | ||
1098 | } else | ||
1099 | acpi_battery_refresh(battery); | ||
1100 | |||
1101 | acpi_battery_init_alarm(battery); | ||
1102 | acpi_battery_get_state(battery); | ||
1055 | break; | 1103 | break; |
1056 | } | 1104 | } |
1057 | 1105 | ||
@@ -1087,7 +1135,7 @@ static int acpi_battery_add(struct acpi_device *device) | |||
1087 | mutex_init(&battery->sysfs_lock); | 1135 | mutex_init(&battery->sysfs_lock); |
1088 | if (acpi_has_method(battery->device->handle, "_BIX")) | 1136 | if (acpi_has_method(battery->device->handle, "_BIX")) |
1089 | set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); | 1137 | set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); |
1090 | result = acpi_battery_update(battery); | 1138 | result = acpi_battery_update(battery, false); |
1091 | if (result) | 1139 | if (result) |
1092 | goto fail; | 1140 | goto fail; |
1093 | #ifdef CONFIG_ACPI_PROCFS_POWER | 1141 | #ifdef CONFIG_ACPI_PROCFS_POWER |
@@ -1107,6 +1155,8 @@ static int acpi_battery_add(struct acpi_device *device) | |||
1107 | battery->pm_nb.notifier_call = battery_notify; | 1155 | battery->pm_nb.notifier_call = battery_notify; |
1108 | register_pm_notifier(&battery->pm_nb); | 1156 | register_pm_notifier(&battery->pm_nb); |
1109 | 1157 | ||
1158 | device_init_wakeup(&device->dev, 1); | ||
1159 | |||
1110 | return result; | 1160 | return result; |
1111 | 1161 | ||
1112 | fail: | 1162 | fail: |
@@ -1123,6 +1173,7 @@ static int acpi_battery_remove(struct acpi_device *device) | |||
1123 | 1173 | ||
1124 | if (!device || !acpi_driver_data(device)) | 1174 | if (!device || !acpi_driver_data(device)) |
1125 | return -EINVAL; | 1175 | return -EINVAL; |
1176 | device_init_wakeup(&device->dev, 0); | ||
1126 | battery = acpi_driver_data(device); | 1177 | battery = acpi_driver_data(device); |
1127 | unregister_pm_notifier(&battery->pm_nb); | 1178 | unregister_pm_notifier(&battery->pm_nb); |
1128 | #ifdef CONFIG_ACPI_PROCFS_POWER | 1179 | #ifdef CONFIG_ACPI_PROCFS_POWER |
@@ -1149,7 +1200,7 @@ static int acpi_battery_resume(struct device *dev) | |||
1149 | return -EINVAL; | 1200 | return -EINVAL; |
1150 | 1201 | ||
1151 | battery->update_time = 0; | 1202 | battery->update_time = 0; |
1152 | acpi_battery_update(battery); | 1203 | acpi_battery_update(battery, true); |
1153 | return 0; | 1204 | return 0; |
1154 | } | 1205 | } |
1155 | #else | 1206 | #else |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index cf925c4f36b7..c5bc8cfe09fa 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -52,6 +52,12 @@ struct proc_dir_entry *acpi_root_dir; | |||
52 | EXPORT_SYMBOL(acpi_root_dir); | 52 | EXPORT_SYMBOL(acpi_root_dir); |
53 | 53 | ||
54 | #ifdef CONFIG_X86 | 54 | #ifdef CONFIG_X86 |
55 | #ifdef CONFIG_ACPI_CUSTOM_DSDT | ||
56 | static inline int set_copy_dsdt(const struct dmi_system_id *id) | ||
57 | { | ||
58 | return 0; | ||
59 | } | ||
60 | #else | ||
55 | static int set_copy_dsdt(const struct dmi_system_id *id) | 61 | static int set_copy_dsdt(const struct dmi_system_id *id) |
56 | { | 62 | { |
57 | printk(KERN_NOTICE "%s detected - " | 63 | printk(KERN_NOTICE "%s detected - " |
@@ -59,6 +65,7 @@ static int set_copy_dsdt(const struct dmi_system_id *id) | |||
59 | acpi_gbl_copy_dsdt_locally = 1; | 65 | acpi_gbl_copy_dsdt_locally = 1; |
60 | return 0; | 66 | return 0; |
61 | } | 67 | } |
68 | #endif | ||
62 | 69 | ||
63 | static struct dmi_system_id dsdt_dmi_table[] __initdata = { | 70 | static struct dmi_system_id dsdt_dmi_table[] __initdata = { |
64 | /* | 71 | /* |
@@ -132,6 +139,21 @@ void acpi_bus_private_data_handler(acpi_handle handle, | |||
132 | } | 139 | } |
133 | EXPORT_SYMBOL(acpi_bus_private_data_handler); | 140 | EXPORT_SYMBOL(acpi_bus_private_data_handler); |
134 | 141 | ||
142 | int acpi_bus_attach_private_data(acpi_handle handle, void *data) | ||
143 | { | ||
144 | acpi_status status; | ||
145 | |||
146 | status = acpi_attach_data(handle, | ||
147 | acpi_bus_private_data_handler, data); | ||
148 | if (ACPI_FAILURE(status)) { | ||
149 | acpi_handle_debug(handle, "Error attaching device data\n"); | ||
150 | return -ENODEV; | ||
151 | } | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | EXPORT_SYMBOL_GPL(acpi_bus_attach_private_data); | ||
156 | |||
135 | int acpi_bus_get_private_data(acpi_handle handle, void **data) | 157 | int acpi_bus_get_private_data(acpi_handle handle, void **data) |
136 | { | 158 | { |
137 | acpi_status status; | 159 | acpi_status status; |
@@ -140,15 +162,20 @@ int acpi_bus_get_private_data(acpi_handle handle, void **data) | |||
140 | return -EINVAL; | 162 | return -EINVAL; |
141 | 163 | ||
142 | status = acpi_get_data(handle, acpi_bus_private_data_handler, data); | 164 | status = acpi_get_data(handle, acpi_bus_private_data_handler, data); |
143 | if (ACPI_FAILURE(status) || !*data) { | 165 | if (ACPI_FAILURE(status)) { |
144 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", | 166 | acpi_handle_debug(handle, "No context for object\n"); |
145 | handle)); | ||
146 | return -ENODEV; | 167 | return -ENODEV; |
147 | } | 168 | } |
148 | 169 | ||
149 | return 0; | 170 | return 0; |
150 | } | 171 | } |
151 | EXPORT_SYMBOL(acpi_bus_get_private_data); | 172 | EXPORT_SYMBOL_GPL(acpi_bus_get_private_data); |
173 | |||
174 | void acpi_bus_detach_private_data(acpi_handle handle) | ||
175 | { | ||
176 | acpi_detach_data(handle, acpi_bus_private_data_handler); | ||
177 | } | ||
178 | EXPORT_SYMBOL_GPL(acpi_bus_detach_private_data); | ||
152 | 179 | ||
153 | void acpi_bus_no_hotplug(acpi_handle handle) | 180 | void acpi_bus_no_hotplug(acpi_handle handle) |
154 | { | 181 | { |
@@ -340,16 +367,18 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | |||
340 | { | 367 | { |
341 | struct acpi_device *adev; | 368 | struct acpi_device *adev; |
342 | struct acpi_driver *driver; | 369 | struct acpi_driver *driver; |
343 | acpi_status status; | ||
344 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 370 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; |
371 | bool hotplug_event = false; | ||
345 | 372 | ||
346 | switch (type) { | 373 | switch (type) { |
347 | case ACPI_NOTIFY_BUS_CHECK: | 374 | case ACPI_NOTIFY_BUS_CHECK: |
348 | acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); | 375 | acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); |
376 | hotplug_event = true; | ||
349 | break; | 377 | break; |
350 | 378 | ||
351 | case ACPI_NOTIFY_DEVICE_CHECK: | 379 | case ACPI_NOTIFY_DEVICE_CHECK: |
352 | acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n"); | 380 | acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n"); |
381 | hotplug_event = true; | ||
353 | break; | 382 | break; |
354 | 383 | ||
355 | case ACPI_NOTIFY_DEVICE_WAKE: | 384 | case ACPI_NOTIFY_DEVICE_WAKE: |
@@ -358,6 +387,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | |||
358 | 387 | ||
359 | case ACPI_NOTIFY_EJECT_REQUEST: | 388 | case ACPI_NOTIFY_EJECT_REQUEST: |
360 | acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); | 389 | acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); |
390 | hotplug_event = true; | ||
361 | break; | 391 | break; |
362 | 392 | ||
363 | case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: | 393 | case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: |
@@ -393,16 +423,9 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | |||
393 | (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) | 423 | (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) |
394 | driver->ops.notify(adev, type); | 424 | driver->ops.notify(adev, type); |
395 | 425 | ||
396 | switch (type) { | 426 | if (hotplug_event && ACPI_SUCCESS(acpi_hotplug_schedule(adev, type))) |
397 | case ACPI_NOTIFY_BUS_CHECK: | 427 | return; |
398 | case ACPI_NOTIFY_DEVICE_CHECK: | 428 | |
399 | case ACPI_NOTIFY_EJECT_REQUEST: | ||
400 | status = acpi_hotplug_schedule(adev, type); | ||
401 | if (ACPI_SUCCESS(status)) | ||
402 | return; | ||
403 | default: | ||
404 | break; | ||
405 | } | ||
406 | acpi_bus_put_acpi_device(adev); | 429 | acpi_bus_put_acpi_device(adev); |
407 | return; | 430 | return; |
408 | 431 | ||
@@ -466,6 +489,9 @@ void __init acpi_early_init(void) | |||
466 | 489 | ||
467 | printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION); | 490 | printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION); |
468 | 491 | ||
492 | /* It's safe to verify table checksums during late stage */ | ||
493 | acpi_gbl_verify_table_checksum = TRUE; | ||
494 | |||
469 | /* enable workarounds, unless strict ACPI spec. compliance */ | 495 | /* enable workarounds, unless strict ACPI spec. compliance */ |
470 | if (!acpi_strict) | 496 | if (!acpi_strict) |
471 | acpi_gbl_enable_interpreter_slack = TRUE; | 497 | acpi_gbl_enable_interpreter_slack = TRUE; |
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 63119d09b354..76f7cff64594 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
@@ -41,6 +41,8 @@ static const struct acpi_device_id container_device_ids[] = { | |||
41 | {"", 0}, | 41 | {"", 0}, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | #ifdef CONFIG_ACPI_CONTAINER | ||
45 | |||
44 | static int acpi_container_offline(struct container_dev *cdev) | 46 | static int acpi_container_offline(struct container_dev *cdev) |
45 | { | 47 | { |
46 | struct acpi_device *adev = ACPI_COMPANION(&cdev->dev); | 48 | struct acpi_device *adev = ACPI_COMPANION(&cdev->dev); |
@@ -109,5 +111,18 @@ static struct acpi_scan_handler container_handler = { | |||
109 | 111 | ||
110 | void __init acpi_container_init(void) | 112 | void __init acpi_container_init(void) |
111 | { | 113 | { |
114 | acpi_scan_add_handler(&container_handler); | ||
115 | } | ||
116 | |||
117 | #else | ||
118 | |||
119 | static struct acpi_scan_handler container_handler = { | ||
120 | .ids = container_device_ids, | ||
121 | }; | ||
122 | |||
123 | void __init acpi_container_init(void) | ||
124 | { | ||
112 | acpi_scan_add_handler_with_hotplug(&container_handler, "container"); | 125 | acpi_scan_add_handler_with_hotplug(&container_handler, "container"); |
113 | } | 126 | } |
127 | |||
128 | #endif /* CONFIG_ACPI_CONTAINER */ | ||
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index d047739f3380..49a51277f81d 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -900,18 +900,47 @@ EXPORT_SYMBOL_GPL(acpi_dev_resume_early); | |||
900 | */ | 900 | */ |
901 | int acpi_subsys_prepare(struct device *dev) | 901 | int acpi_subsys_prepare(struct device *dev) |
902 | { | 902 | { |
903 | /* | 903 | struct acpi_device *adev = ACPI_COMPANION(dev); |
904 | * Devices having power.ignore_children set may still be necessary for | 904 | u32 sys_target; |
905 | * suspending their children in the next phase of device suspend. | 905 | int ret, state; |
906 | */ | 906 | |
907 | if (dev->power.ignore_children) | 907 | ret = pm_generic_prepare(dev); |
908 | pm_runtime_resume(dev); | 908 | if (ret < 0) |
909 | return ret; | ||
910 | |||
911 | if (!adev || !pm_runtime_suspended(dev) | ||
912 | || device_may_wakeup(dev) != !!adev->wakeup.prepare_count) | ||
913 | return 0; | ||
914 | |||
915 | sys_target = acpi_target_system_state(); | ||
916 | if (sys_target == ACPI_STATE_S0) | ||
917 | return 1; | ||
909 | 918 | ||
910 | return pm_generic_prepare(dev); | 919 | if (adev->power.flags.dsw_present) |
920 | return 0; | ||
921 | |||
922 | ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state); | ||
923 | return !ret && state == adev->power.state; | ||
911 | } | 924 | } |
912 | EXPORT_SYMBOL_GPL(acpi_subsys_prepare); | 925 | EXPORT_SYMBOL_GPL(acpi_subsys_prepare); |
913 | 926 | ||
914 | /** | 927 | /** |
928 | * acpi_subsys_complete - Finalize device's resume during system resume. | ||
929 | * @dev: Device to handle. | ||
930 | */ | ||
931 | void acpi_subsys_complete(struct device *dev) | ||
932 | { | ||
933 | /* | ||
934 | * If the device had been runtime-suspended before the system went into | ||
935 | * the sleep state it is going out of and it has never been resumed till | ||
936 | * now, resume it in case the firmware powered it up. | ||
937 | */ | ||
938 | if (dev->power.direct_complete) | ||
939 | pm_request_resume(dev); | ||
940 | } | ||
941 | EXPORT_SYMBOL_GPL(acpi_subsys_complete); | ||
942 | |||
943 | /** | ||
915 | * acpi_subsys_suspend - Run the device driver's suspend callback. | 944 | * acpi_subsys_suspend - Run the device driver's suspend callback. |
916 | * @dev: Device to handle. | 945 | * @dev: Device to handle. |
917 | * | 946 | * |
@@ -923,6 +952,7 @@ int acpi_subsys_suspend(struct device *dev) | |||
923 | pm_runtime_resume(dev); | 952 | pm_runtime_resume(dev); |
924 | return pm_generic_suspend(dev); | 953 | return pm_generic_suspend(dev); |
925 | } | 954 | } |
955 | EXPORT_SYMBOL_GPL(acpi_subsys_suspend); | ||
926 | 956 | ||
927 | /** | 957 | /** |
928 | * acpi_subsys_suspend_late - Suspend device using ACPI. | 958 | * acpi_subsys_suspend_late - Suspend device using ACPI. |
@@ -968,6 +998,7 @@ int acpi_subsys_freeze(struct device *dev) | |||
968 | pm_runtime_resume(dev); | 998 | pm_runtime_resume(dev); |
969 | return pm_generic_freeze(dev); | 999 | return pm_generic_freeze(dev); |
970 | } | 1000 | } |
1001 | EXPORT_SYMBOL_GPL(acpi_subsys_freeze); | ||
971 | 1002 | ||
972 | #endif /* CONFIG_PM_SLEEP */ | 1003 | #endif /* CONFIG_PM_SLEEP */ |
973 | 1004 | ||
@@ -979,6 +1010,7 @@ static struct dev_pm_domain acpi_general_pm_domain = { | |||
979 | #endif | 1010 | #endif |
980 | #ifdef CONFIG_PM_SLEEP | 1011 | #ifdef CONFIG_PM_SLEEP |
981 | .prepare = acpi_subsys_prepare, | 1012 | .prepare = acpi_subsys_prepare, |
1013 | .complete = acpi_subsys_complete, | ||
982 | .suspend = acpi_subsys_suspend, | 1014 | .suspend = acpi_subsys_suspend, |
983 | .suspend_late = acpi_subsys_suspend_late, | 1015 | .suspend_late = acpi_subsys_suspend_late, |
984 | .resume_early = acpi_subsys_resume_early, | 1016 | .resume_early = acpi_subsys_resume_early, |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 957391306cbf..7de5b603f272 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -30,12 +30,10 @@ void acpi_pci_root_init(void); | |||
30 | void acpi_pci_link_init(void); | 30 | void acpi_pci_link_init(void); |
31 | void acpi_processor_init(void); | 31 | void acpi_processor_init(void); |
32 | void acpi_platform_init(void); | 32 | void acpi_platform_init(void); |
33 | void acpi_pnp_init(void); | ||
33 | int acpi_sysfs_init(void); | 34 | int acpi_sysfs_init(void); |
34 | #ifdef CONFIG_ACPI_CONTAINER | ||
35 | void acpi_container_init(void); | 35 | void acpi_container_init(void); |
36 | #else | 36 | void acpi_memory_hotplug_init(void); |
37 | static inline void acpi_container_init(void) {} | ||
38 | #endif | ||
39 | #ifdef CONFIG_ACPI_DOCK | 37 | #ifdef CONFIG_ACPI_DOCK |
40 | void register_dock_dependent_device(struct acpi_device *adev, | 38 | void register_dock_dependent_device(struct acpi_device *adev, |
41 | acpi_handle dshandle); | 39 | acpi_handle dshandle); |
@@ -47,11 +45,6 @@ static inline void register_dock_dependent_device(struct acpi_device *adev, | |||
47 | static inline int dock_notify(struct acpi_device *adev, u32 event) { return -ENODEV; } | 45 | static inline int dock_notify(struct acpi_device *adev, u32 event) { return -ENODEV; } |
48 | static inline void acpi_dock_add(struct acpi_device *adev) {} | 46 | static inline void acpi_dock_add(struct acpi_device *adev) {} |
49 | #endif | 47 | #endif |
50 | #ifdef CONFIG_ACPI_HOTPLUG_MEMORY | ||
51 | void acpi_memory_hotplug_init(void); | ||
52 | #else | ||
53 | static inline void acpi_memory_hotplug_init(void) {} | ||
54 | #endif | ||
55 | #ifdef CONFIG_X86 | 48 | #ifdef CONFIG_X86 |
56 | void acpi_cmos_rtc_init(void); | 49 | void acpi_cmos_rtc_init(void); |
57 | #else | 50 | #else |
@@ -72,11 +65,7 @@ int acpi_debugfs_init(void); | |||
72 | #else | 65 | #else |
73 | static inline void acpi_debugfs_init(void) { return; } | 66 | static inline void acpi_debugfs_init(void) { return; } |
74 | #endif | 67 | #endif |
75 | #ifdef CONFIG_X86_INTEL_LPSS | ||
76 | void acpi_lpss_init(void); | 68 | void acpi_lpss_init(void); |
77 | #else | ||
78 | static inline void acpi_lpss_init(void) {} | ||
79 | #endif | ||
80 | 69 | ||
81 | acpi_status acpi_hotplug_schedule(struct acpi_device *adev, u32 src); | 70 | acpi_status acpi_hotplug_schedule(struct acpi_device *adev, u32 src); |
82 | bool acpi_queue_hotplug_work(struct work_struct *work); | 71 | bool acpi_queue_hotplug_work(struct work_struct *work); |
@@ -180,8 +169,7 @@ static inline void suspend_nvs_restore(void) {} | |||
180 | -------------------------------------------------------------------------- */ | 169 | -------------------------------------------------------------------------- */ |
181 | struct platform_device; | 170 | struct platform_device; |
182 | 171 | ||
183 | int acpi_create_platform_device(struct acpi_device *adev, | 172 | struct platform_device *acpi_create_platform_device(struct acpi_device *adev); |
184 | const struct acpi_device_id *id); | ||
185 | 173 | ||
186 | /*-------------------------------------------------------------------------- | 174 | /*-------------------------------------------------------------------------- |
187 | Video | 175 | Video |
diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c index de4fe03873c5..85287b8fe3aa 100644 --- a/drivers/acpi/nvs.c +++ b/drivers/acpi/nvs.c | |||
@@ -139,8 +139,8 @@ void suspend_nvs_free(void) | |||
139 | iounmap(entry->kaddr); | 139 | iounmap(entry->kaddr); |
140 | entry->unmap = false; | 140 | entry->unmap = false; |
141 | } else { | 141 | } else { |
142 | acpi_os_unmap_memory(entry->kaddr, | 142 | acpi_os_unmap_iomem(entry->kaddr, |
143 | entry->size); | 143 | entry->size); |
144 | } | 144 | } |
145 | entry->kaddr = NULL; | 145 | entry->kaddr = NULL; |
146 | } | 146 | } |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 6776c599816f..147bc1b91b42 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -355,7 +355,7 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr) | |||
355 | } | 355 | } |
356 | 356 | ||
357 | void __iomem *__init_refok | 357 | void __iomem *__init_refok |
358 | acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | 358 | acpi_os_map_iomem(acpi_physical_address phys, acpi_size size) |
359 | { | 359 | { |
360 | struct acpi_ioremap *map; | 360 | struct acpi_ioremap *map; |
361 | void __iomem *virt; | 361 | void __iomem *virt; |
@@ -401,10 +401,17 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | |||
401 | 401 | ||
402 | list_add_tail_rcu(&map->list, &acpi_ioremaps); | 402 | list_add_tail_rcu(&map->list, &acpi_ioremaps); |
403 | 403 | ||
404 | out: | 404 | out: |
405 | mutex_unlock(&acpi_ioremap_lock); | 405 | mutex_unlock(&acpi_ioremap_lock); |
406 | return map->virt + (phys - map->phys); | 406 | return map->virt + (phys - map->phys); |
407 | } | 407 | } |
408 | EXPORT_SYMBOL_GPL(acpi_os_map_iomem); | ||
409 | |||
410 | void *__init_refok | ||
411 | acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | ||
412 | { | ||
413 | return (void *)acpi_os_map_iomem(phys, size); | ||
414 | } | ||
408 | EXPORT_SYMBOL_GPL(acpi_os_map_memory); | 415 | EXPORT_SYMBOL_GPL(acpi_os_map_memory); |
409 | 416 | ||
410 | static void acpi_os_drop_map_ref(struct acpi_ioremap *map) | 417 | static void acpi_os_drop_map_ref(struct acpi_ioremap *map) |
@@ -422,7 +429,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map) | |||
422 | } | 429 | } |
423 | } | 430 | } |
424 | 431 | ||
425 | void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) | 432 | void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size) |
426 | { | 433 | { |
427 | struct acpi_ioremap *map; | 434 | struct acpi_ioremap *map; |
428 | 435 | ||
@@ -443,6 +450,12 @@ void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) | |||
443 | 450 | ||
444 | acpi_os_map_cleanup(map); | 451 | acpi_os_map_cleanup(map); |
445 | } | 452 | } |
453 | EXPORT_SYMBOL_GPL(acpi_os_unmap_iomem); | ||
454 | |||
455 | void __ref acpi_os_unmap_memory(void *virt, acpi_size size) | ||
456 | { | ||
457 | return acpi_os_unmap_iomem((void __iomem *)virt, size); | ||
458 | } | ||
446 | EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); | 459 | EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); |
447 | 460 | ||
448 | void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size) | 461 | void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size) |
@@ -464,7 +477,7 @@ int acpi_os_map_generic_address(struct acpi_generic_address *gas) | |||
464 | if (!addr || !gas->bit_width) | 477 | if (!addr || !gas->bit_width) |
465 | return -EINVAL; | 478 | return -EINVAL; |
466 | 479 | ||
467 | virt = acpi_os_map_memory(addr, gas->bit_width / 8); | 480 | virt = acpi_os_map_iomem(addr, gas->bit_width / 8); |
468 | if (!virt) | 481 | if (!virt) |
469 | return -EIO; | 482 | return -EIO; |
470 | 483 | ||
@@ -1770,16 +1783,15 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) | |||
1770 | } | 1783 | } |
1771 | #endif | 1784 | #endif |
1772 | 1785 | ||
1773 | static int __init acpi_no_auto_ssdt_setup(char *s) | 1786 | static int __init acpi_no_static_ssdt_setup(char *s) |
1774 | { | 1787 | { |
1775 | printk(KERN_NOTICE PREFIX "SSDT auto-load disabled\n"); | 1788 | acpi_gbl_disable_ssdt_table_install = TRUE; |
1789 | pr_info("ACPI: static SSDT installation disabled\n"); | ||
1776 | 1790 | ||
1777 | acpi_gbl_disable_ssdt_table_load = TRUE; | 1791 | return 0; |
1778 | |||
1779 | return 1; | ||
1780 | } | 1792 | } |
1781 | 1793 | ||
1782 | __setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup); | 1794 | early_param("acpi_no_static_ssdt", acpi_no_static_ssdt_setup); |
1783 | 1795 | ||
1784 | static int __init acpi_disable_return_repair(char *s) | 1796 | static int __init acpi_disable_return_repair(char *s) |
1785 | { | 1797 | { |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 7f70f3182d50..4fcbd670415c 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -121,6 +121,13 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, | |||
121 | struct acpi_processor *pr = per_cpu(processors, cpu); | 121 | struct acpi_processor *pr = per_cpu(processors, cpu); |
122 | struct acpi_device *device; | 122 | struct acpi_device *device; |
123 | 123 | ||
124 | /* | ||
125 | * CPU_STARTING and CPU_DYING must not sleep. Return here since | ||
126 | * acpi_bus_get_device() may sleep. | ||
127 | */ | ||
128 | if (action == CPU_STARTING || action == CPU_DYING) | ||
129 | return NOTIFY_DONE; | ||
130 | |||
124 | if (!pr || acpi_bus_get_device(pr->handle, &device)) | 131 | if (!pr || acpi_bus_get_device(pr->handle, &device)) |
125 | return NOTIFY_DONE; | 132 | return NOTIFY_DONE; |
126 | 133 | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7efe546a8c42..f775fa0d850f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -84,7 +84,7 @@ EXPORT_SYMBOL_GPL(acpi_initialize_hp_context); | |||
84 | 84 | ||
85 | int acpi_scan_add_handler(struct acpi_scan_handler *handler) | 85 | int acpi_scan_add_handler(struct acpi_scan_handler *handler) |
86 | { | 86 | { |
87 | if (!handler || !handler->attach) | 87 | if (!handler) |
88 | return -EINVAL; | 88 | return -EINVAL; |
89 | 89 | ||
90 | list_add_tail(&handler->list_node, &acpi_scan_handlers_list); | 90 | list_add_tail(&handler->list_node, &acpi_scan_handlers_list); |
@@ -1551,9 +1551,13 @@ static void acpi_bus_get_power_flags(struct acpi_device *device) | |||
1551 | */ | 1551 | */ |
1552 | if (acpi_has_method(device->handle, "_PSC")) | 1552 | if (acpi_has_method(device->handle, "_PSC")) |
1553 | device->power.flags.explicit_get = 1; | 1553 | device->power.flags.explicit_get = 1; |
1554 | |||
1554 | if (acpi_has_method(device->handle, "_IRC")) | 1555 | if (acpi_has_method(device->handle, "_IRC")) |
1555 | device->power.flags.inrush_current = 1; | 1556 | device->power.flags.inrush_current = 1; |
1556 | 1557 | ||
1558 | if (acpi_has_method(device->handle, "_DSW")) | ||
1559 | device->power.flags.dsw_present = 1; | ||
1560 | |||
1557 | /* | 1561 | /* |
1558 | * Enumerate supported power management states | 1562 | * Enumerate supported power management states |
1559 | */ | 1563 | */ |
@@ -1793,8 +1797,10 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, | |||
1793 | return; | 1797 | return; |
1794 | } | 1798 | } |
1795 | 1799 | ||
1796 | if (info->valid & ACPI_VALID_HID) | 1800 | if (info->valid & ACPI_VALID_HID) { |
1797 | acpi_add_id(pnp, info->hardware_id.string); | 1801 | acpi_add_id(pnp, info->hardware_id.string); |
1802 | pnp->type.platform_id = 1; | ||
1803 | } | ||
1798 | if (info->valid & ACPI_VALID_CID) { | 1804 | if (info->valid & ACPI_VALID_CID) { |
1799 | cid_list = &info->compatible_id_list; | 1805 | cid_list = &info->compatible_id_list; |
1800 | for (i = 0; i < cid_list->count; i++) | 1806 | for (i = 0; i < cid_list->count; i++) |
@@ -1973,6 +1979,9 @@ static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler, | |||
1973 | { | 1979 | { |
1974 | const struct acpi_device_id *devid; | 1980 | const struct acpi_device_id *devid; |
1975 | 1981 | ||
1982 | if (handler->match) | ||
1983 | return handler->match(idstr, matchid); | ||
1984 | |||
1976 | for (devid = handler->ids; devid->id[0]; devid++) | 1985 | for (devid = handler->ids; devid->id[0]; devid++) |
1977 | if (!strcmp((char *)devid->id, idstr)) { | 1986 | if (!strcmp((char *)devid->id, idstr)) { |
1978 | if (matchid) | 1987 | if (matchid) |
@@ -2061,6 +2070,44 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, | |||
2061 | return AE_OK; | 2070 | return AE_OK; |
2062 | } | 2071 | } |
2063 | 2072 | ||
2073 | static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data) | ||
2074 | { | ||
2075 | bool *is_spi_i2c_slave_p = data; | ||
2076 | |||
2077 | if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) | ||
2078 | return 1; | ||
2079 | |||
2080 | /* | ||
2081 | * devices that are connected to UART still need to be enumerated to | ||
2082 | * platform bus | ||
2083 | */ | ||
2084 | if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART) | ||
2085 | *is_spi_i2c_slave_p = true; | ||
2086 | |||
2087 | /* no need to do more checking */ | ||
2088 | return -1; | ||
2089 | } | ||
2090 | |||
2091 | static void acpi_default_enumeration(struct acpi_device *device) | ||
2092 | { | ||
2093 | struct list_head resource_list; | ||
2094 | bool is_spi_i2c_slave = false; | ||
2095 | |||
2096 | if (!device->pnp.type.platform_id || device->handler) | ||
2097 | return; | ||
2098 | |||
2099 | /* | ||
2100 | * Do not enemerate SPI/I2C slaves as they will be enuerated by their | ||
2101 | * respective parents. | ||
2102 | */ | ||
2103 | INIT_LIST_HEAD(&resource_list); | ||
2104 | acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave, | ||
2105 | &is_spi_i2c_slave); | ||
2106 | acpi_dev_free_resource_list(&resource_list); | ||
2107 | if (!is_spi_i2c_slave) | ||
2108 | acpi_create_platform_device(device); | ||
2109 | } | ||
2110 | |||
2064 | static int acpi_scan_attach_handler(struct acpi_device *device) | 2111 | static int acpi_scan_attach_handler(struct acpi_device *device) |
2065 | { | 2112 | { |
2066 | struct acpi_hardware_id *hwid; | 2113 | struct acpi_hardware_id *hwid; |
@@ -2072,6 +2119,10 @@ static int acpi_scan_attach_handler(struct acpi_device *device) | |||
2072 | 2119 | ||
2073 | handler = acpi_scan_match_handler(hwid->id, &devid); | 2120 | handler = acpi_scan_match_handler(hwid->id, &devid); |
2074 | if (handler) { | 2121 | if (handler) { |
2122 | if (!handler->attach) { | ||
2123 | device->pnp.type.platform_id = 0; | ||
2124 | continue; | ||
2125 | } | ||
2075 | device->handler = handler; | 2126 | device->handler = handler; |
2076 | ret = handler->attach(device, devid); | 2127 | ret = handler->attach(device, devid); |
2077 | if (ret > 0) | 2128 | if (ret > 0) |
@@ -2082,6 +2133,9 @@ static int acpi_scan_attach_handler(struct acpi_device *device) | |||
2082 | break; | 2133 | break; |
2083 | } | 2134 | } |
2084 | } | 2135 | } |
2136 | if (!ret) | ||
2137 | acpi_default_enumeration(device); | ||
2138 | |||
2085 | return ret; | 2139 | return ret; |
2086 | } | 2140 | } |
2087 | 2141 | ||
@@ -2241,11 +2295,11 @@ int __init acpi_scan_init(void) | |||
2241 | acpi_pci_root_init(); | 2295 | acpi_pci_root_init(); |
2242 | acpi_pci_link_init(); | 2296 | acpi_pci_link_init(); |
2243 | acpi_processor_init(); | 2297 | acpi_processor_init(); |
2244 | acpi_platform_init(); | ||
2245 | acpi_lpss_init(); | 2298 | acpi_lpss_init(); |
2246 | acpi_cmos_rtc_init(); | 2299 | acpi_cmos_rtc_init(); |
2247 | acpi_container_init(); | 2300 | acpi_container_init(); |
2248 | acpi_memory_hotplug_init(); | 2301 | acpi_memory_hotplug_init(); |
2302 | acpi_pnp_init(); | ||
2249 | 2303 | ||
2250 | mutex_lock(&acpi_scan_lock); | 2304 | mutex_lock(&acpi_scan_lock); |
2251 | /* | 2305 | /* |
@@ -2259,12 +2313,16 @@ int __init acpi_scan_init(void) | |||
2259 | if (result) | 2313 | if (result) |
2260 | goto out; | 2314 | goto out; |
2261 | 2315 | ||
2262 | result = acpi_bus_scan_fixed(); | 2316 | /* Fixed feature devices do not exist on HW-reduced platform */ |
2263 | if (result) { | 2317 | if (!acpi_gbl_reduced_hardware) { |
2264 | acpi_detach_data(acpi_root->handle, acpi_scan_drop_device); | 2318 | result = acpi_bus_scan_fixed(); |
2265 | acpi_device_del(acpi_root); | 2319 | if (result) { |
2266 | put_device(&acpi_root->dev); | 2320 | acpi_detach_data(acpi_root->handle, |
2267 | goto out; | 2321 | acpi_scan_drop_device); |
2322 | acpi_device_del(acpi_root); | ||
2323 | put_device(&acpi_root->dev); | ||
2324 | goto out; | ||
2325 | } | ||
2268 | } | 2326 | } |
2269 | 2327 | ||
2270 | acpi_update_all_gpes(); | 2328 | acpi_update_all_gpes(); |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index c40fb2e81bbc..c11e3795431b 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -89,6 +89,7 @@ u32 acpi_target_system_state(void) | |||
89 | { | 89 | { |
90 | return acpi_target_sleep_state; | 90 | return acpi_target_sleep_state; |
91 | } | 91 | } |
92 | EXPORT_SYMBOL_GPL(acpi_target_system_state); | ||
92 | 93 | ||
93 | static bool pwr_btn_event_pending; | 94 | static bool pwr_btn_event_pending; |
94 | 95 | ||
@@ -611,6 +612,22 @@ static const struct platform_suspend_ops acpi_suspend_ops_old = { | |||
611 | .recover = acpi_pm_finish, | 612 | .recover = acpi_pm_finish, |
612 | }; | 613 | }; |
613 | 614 | ||
615 | static int acpi_freeze_begin(void) | ||
616 | { | ||
617 | acpi_scan_lock_acquire(); | ||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | static void acpi_freeze_end(void) | ||
622 | { | ||
623 | acpi_scan_lock_release(); | ||
624 | } | ||
625 | |||
626 | static const struct platform_freeze_ops acpi_freeze_ops = { | ||
627 | .begin = acpi_freeze_begin, | ||
628 | .end = acpi_freeze_end, | ||
629 | }; | ||
630 | |||
614 | static void acpi_sleep_suspend_setup(void) | 631 | static void acpi_sleep_suspend_setup(void) |
615 | { | 632 | { |
616 | int i; | 633 | int i; |
@@ -621,7 +638,9 @@ static void acpi_sleep_suspend_setup(void) | |||
621 | 638 | ||
622 | suspend_set_ops(old_suspend_ordering ? | 639 | suspend_set_ops(old_suspend_ordering ? |
623 | &acpi_suspend_ops_old : &acpi_suspend_ops); | 640 | &acpi_suspend_ops_old : &acpi_suspend_ops); |
641 | freeze_set_ops(&acpi_freeze_ops); | ||
624 | } | 642 | } |
643 | |||
625 | #else /* !CONFIG_SUSPEND */ | 644 | #else /* !CONFIG_SUSPEND */ |
626 | static inline void acpi_sleep_suspend_setup(void) {} | 645 | static inline void acpi_sleep_suspend_setup(void) {} |
627 | #endif /* !CONFIG_SUSPEND */ | 646 | #endif /* !CONFIG_SUSPEND */ |
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 21782290df41..05550ba44d32 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
@@ -44,6 +44,12 @@ static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; | |||
44 | 44 | ||
45 | static int acpi_apic_instance __initdata; | 45 | static int acpi_apic_instance __initdata; |
46 | 46 | ||
47 | /* | ||
48 | * Disable table checksum verification for the early stage due to the size | ||
49 | * limitation of the current x86 early mapping implementation. | ||
50 | */ | ||
51 | static bool acpi_verify_table_checksum __initdata = false; | ||
52 | |||
47 | void acpi_table_print_madt_entry(struct acpi_subtable_header *header) | 53 | void acpi_table_print_madt_entry(struct acpi_subtable_header *header) |
48 | { | 54 | { |
49 | if (!header) | 55 | if (!header) |
@@ -333,6 +339,14 @@ int __init acpi_table_init(void) | |||
333 | { | 339 | { |
334 | acpi_status status; | 340 | acpi_status status; |
335 | 341 | ||
342 | if (acpi_verify_table_checksum) { | ||
343 | pr_info("Early table checksum verification enabled\n"); | ||
344 | acpi_gbl_verify_table_checksum = TRUE; | ||
345 | } else { | ||
346 | pr_info("Early table checksum verification disabled\n"); | ||
347 | acpi_gbl_verify_table_checksum = FALSE; | ||
348 | } | ||
349 | |||
336 | status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); | 350 | status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); |
337 | if (ACPI_FAILURE(status)) | 351 | if (ACPI_FAILURE(status)) |
338 | return -EINVAL; | 352 | return -EINVAL; |
@@ -354,3 +368,12 @@ static int __init acpi_parse_apic_instance(char *str) | |||
354 | } | 368 | } |
355 | 369 | ||
356 | early_param("acpi_apic_instance", acpi_parse_apic_instance); | 370 | early_param("acpi_apic_instance", acpi_parse_apic_instance); |
371 | |||
372 | static int __init acpi_force_table_verification_setup(char *s) | ||
373 | { | ||
374 | acpi_verify_table_checksum = true; | ||
375 | |||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | early_param("acpi_force_table_verification", acpi_force_table_verification_setup); | ||
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 25bbc55dca89..112817e963e0 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -925,13 +925,10 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) | |||
925 | if (result) | 925 | if (result) |
926 | return result; | 926 | return result; |
927 | 927 | ||
928 | status = acpi_attach_data(tz->device->handle, | 928 | status = acpi_bus_attach_private_data(tz->device->handle, |
929 | acpi_bus_private_data_handler, | 929 | tz->thermal_zone); |
930 | tz->thermal_zone); | 930 | if (ACPI_FAILURE(status)) |
931 | if (ACPI_FAILURE(status)) { | ||
932 | pr_err(PREFIX "Error attaching device data\n"); | ||
933 | return -ENODEV; | 931 | return -ENODEV; |
934 | } | ||
935 | 932 | ||
936 | tz->tz_enabled = 1; | 933 | tz->tz_enabled = 1; |
937 | 934 | ||
@@ -946,7 +943,7 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) | |||
946 | sysfs_remove_link(&tz->thermal_zone->device.kobj, "device"); | 943 | sysfs_remove_link(&tz->thermal_zone->device.kobj, "device"); |
947 | thermal_zone_device_unregister(tz->thermal_zone); | 944 | thermal_zone_device_unregister(tz->thermal_zone); |
948 | tz->thermal_zone = NULL; | 945 | tz->thermal_zone = NULL; |
949 | acpi_detach_data(tz->device->handle, acpi_bus_private_data_handler); | 946 | acpi_bus_detach_private_data(tz->device->handle); |
950 | } | 947 | } |
951 | 948 | ||
952 | 949 | ||
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index bba526148583..07c8c5a5ee95 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/hardirq.h> | 31 | #include <linux/hardirq.h> |
32 | #include <linux/acpi.h> | 32 | #include <linux/acpi.h> |
33 | #include <linux/dynamic_debug.h> | ||
33 | 34 | ||
34 | #include "internal.h" | 35 | #include "internal.h" |
35 | 36 | ||
@@ -457,6 +458,24 @@ acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code, | |||
457 | EXPORT_SYMBOL(acpi_evaluate_ost); | 458 | EXPORT_SYMBOL(acpi_evaluate_ost); |
458 | 459 | ||
459 | /** | 460 | /** |
461 | * acpi_handle_path: Return the object path of handle | ||
462 | * | ||
463 | * Caller must free the returned buffer | ||
464 | */ | ||
465 | static char *acpi_handle_path(acpi_handle handle) | ||
466 | { | ||
467 | struct acpi_buffer buffer = { | ||
468 | .length = ACPI_ALLOCATE_BUFFER, | ||
469 | .pointer = NULL | ||
470 | }; | ||
471 | |||
472 | if (in_interrupt() || | ||
473 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer) != AE_OK) | ||
474 | return NULL; | ||
475 | return buffer.pointer; | ||
476 | } | ||
477 | |||
478 | /** | ||
460 | * acpi_handle_printk: Print message with ACPI prefix and object path | 479 | * acpi_handle_printk: Print message with ACPI prefix and object path |
461 | * | 480 | * |
462 | * This function is called through acpi_handle_<level> macros and prints | 481 | * This function is called through acpi_handle_<level> macros and prints |
@@ -469,29 +488,50 @@ acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...) | |||
469 | { | 488 | { |
470 | struct va_format vaf; | 489 | struct va_format vaf; |
471 | va_list args; | 490 | va_list args; |
472 | struct acpi_buffer buffer = { | ||
473 | .length = ACPI_ALLOCATE_BUFFER, | ||
474 | .pointer = NULL | ||
475 | }; | ||
476 | const char *path; | 491 | const char *path; |
477 | 492 | ||
478 | va_start(args, fmt); | 493 | va_start(args, fmt); |
479 | vaf.fmt = fmt; | 494 | vaf.fmt = fmt; |
480 | vaf.va = &args; | 495 | vaf.va = &args; |
481 | 496 | ||
482 | if (in_interrupt() || | 497 | path = acpi_handle_path(handle); |
483 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer) != AE_OK) | 498 | printk("%sACPI: %s: %pV", level, path ? path : "<n/a>" , &vaf); |
484 | path = "<n/a>"; | ||
485 | else | ||
486 | path = buffer.pointer; | ||
487 | |||
488 | printk("%sACPI: %s: %pV", level, path, &vaf); | ||
489 | 499 | ||
490 | va_end(args); | 500 | va_end(args); |
491 | kfree(buffer.pointer); | 501 | kfree(path); |
492 | } | 502 | } |
493 | EXPORT_SYMBOL(acpi_handle_printk); | 503 | EXPORT_SYMBOL(acpi_handle_printk); |
494 | 504 | ||
505 | #if defined(CONFIG_DYNAMIC_DEBUG) | ||
506 | /** | ||
507 | * __acpi_handle_debug: pr_debug with ACPI prefix and object path | ||
508 | * | ||
509 | * This function is called through acpi_handle_debug macro and debug | ||
510 | * prints a message with ACPI prefix and object path. This function | ||
511 | * acquires the global namespace mutex to obtain an object path. In | ||
512 | * interrupt context, it shows the object path as <n/a>. | ||
513 | */ | ||
514 | void | ||
515 | __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, | ||
516 | const char *fmt, ...) | ||
517 | { | ||
518 | struct va_format vaf; | ||
519 | va_list args; | ||
520 | const char *path; | ||
521 | |||
522 | va_start(args, fmt); | ||
523 | vaf.fmt = fmt; | ||
524 | vaf.va = &args; | ||
525 | |||
526 | path = acpi_handle_path(handle); | ||
527 | __dynamic_pr_debug(descriptor, "ACPI: %s: %pV", path ? path : "<n/a>", &vaf); | ||
528 | |||
529 | va_end(args); | ||
530 | kfree(path); | ||
531 | } | ||
532 | EXPORT_SYMBOL(__acpi_handle_debug); | ||
533 | #endif | ||
534 | |||
495 | /** | 535 | /** |
496 | * acpi_has_method: Check whether @handle has a method named @name | 536 | * acpi_has_method: Check whether @handle has a method named @name |
497 | * @handle: ACPI device handle | 537 | * @handle: ACPI device handle |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index f8bc5a755dda..101fb090dcb9 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -68,7 +68,7 @@ MODULE_AUTHOR("Bruno Ducrot"); | |||
68 | MODULE_DESCRIPTION("ACPI Video Driver"); | 68 | MODULE_DESCRIPTION("ACPI Video Driver"); |
69 | MODULE_LICENSE("GPL"); | 69 | MODULE_LICENSE("GPL"); |
70 | 70 | ||
71 | static bool brightness_switch_enabled = 1; | 71 | static bool brightness_switch_enabled; |
72 | module_param(brightness_switch_enabled, bool, 0644); | 72 | module_param(brightness_switch_enabled, bool, 0644); |
73 | 73 | ||
74 | /* | 74 | /* |
@@ -150,6 +150,8 @@ struct acpi_video_enumerated_device { | |||
150 | 150 | ||
151 | struct acpi_video_bus { | 151 | struct acpi_video_bus { |
152 | struct acpi_device *device; | 152 | struct acpi_device *device; |
153 | bool backlight_registered; | ||
154 | bool backlight_notifier_registered; | ||
153 | u8 dos_setting; | 155 | u8 dos_setting; |
154 | struct acpi_video_enumerated_device *attached_array; | 156 | struct acpi_video_enumerated_device *attached_array; |
155 | u8 attached_count; | 157 | u8 attached_count; |
@@ -161,6 +163,7 @@ struct acpi_video_bus { | |||
161 | struct input_dev *input; | 163 | struct input_dev *input; |
162 | char phys[32]; /* for input device */ | 164 | char phys[32]; /* for input device */ |
163 | struct notifier_block pm_nb; | 165 | struct notifier_block pm_nb; |
166 | struct notifier_block backlight_nb; | ||
164 | }; | 167 | }; |
165 | 168 | ||
166 | struct acpi_video_device_flags { | 169 | struct acpi_video_device_flags { |
@@ -473,6 +476,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
473 | }, | 476 | }, |
474 | { | 477 | { |
475 | .callback = video_set_use_native_backlight, | 478 | .callback = video_set_use_native_backlight, |
479 | .ident = "ThinkPad W530", | ||
480 | .matches = { | ||
481 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
482 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W530"), | ||
483 | }, | ||
484 | }, | ||
485 | { | ||
486 | .callback = video_set_use_native_backlight, | ||
476 | .ident = "ThinkPad X1 Carbon", | 487 | .ident = "ThinkPad X1 Carbon", |
477 | .matches = { | 488 | .matches = { |
478 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 489 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
@@ -488,6 +499,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
488 | }, | 499 | }, |
489 | }, | 500 | }, |
490 | { | 501 | { |
502 | .callback = video_set_use_native_backlight, | ||
503 | .ident = "Lenovo Yoga 2 11", | ||
504 | .matches = { | ||
505 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
506 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2 11"), | ||
507 | }, | ||
508 | }, | ||
509 | { | ||
491 | .callback = video_set_use_native_backlight, | 510 | .callback = video_set_use_native_backlight, |
492 | .ident = "Thinkpad Helix", | 511 | .ident = "Thinkpad Helix", |
493 | .matches = { | 512 | .matches = { |
@@ -521,6 +540,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
521 | }, | 540 | }, |
522 | { | 541 | { |
523 | .callback = video_set_use_native_backlight, | 542 | .callback = video_set_use_native_backlight, |
543 | .ident = "Acer Aspire V5-171", | ||
544 | .matches = { | ||
545 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
546 | DMI_MATCH(DMI_PRODUCT_NAME, "V5-171"), | ||
547 | }, | ||
548 | }, | ||
549 | { | ||
550 | .callback = video_set_use_native_backlight, | ||
524 | .ident = "Acer Aspire V5-431", | 551 | .ident = "Acer Aspire V5-431", |
525 | .matches = { | 552 | .matches = { |
526 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 553 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
@@ -528,6 +555,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
528 | }, | 555 | }, |
529 | }, | 556 | }, |
530 | { | 557 | { |
558 | .callback = video_set_use_native_backlight, | ||
559 | .ident = "Acer Aspire V5-471G", | ||
560 | .matches = { | ||
561 | DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), | ||
562 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-471G"), | ||
563 | }, | ||
564 | }, | ||
565 | { | ||
531 | .callback = video_set_use_native_backlight, | 566 | .callback = video_set_use_native_backlight, |
532 | .ident = "HP ProBook 4340s", | 567 | .ident = "HP ProBook 4340s", |
533 | .matches = { | 568 | .matches = { |
@@ -579,6 +614,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
579 | }, | 614 | }, |
580 | { | 615 | { |
581 | .callback = video_set_use_native_backlight, | 616 | .callback = video_set_use_native_backlight, |
617 | .ident = "HP EliteBook 8470p", | ||
618 | .matches = { | ||
619 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
620 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 8470p"), | ||
621 | }, | ||
622 | }, | ||
623 | { | ||
624 | .callback = video_set_use_native_backlight, | ||
582 | .ident = "HP EliteBook 8780w", | 625 | .ident = "HP EliteBook 8780w", |
583 | .matches = { | 626 | .matches = { |
584 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 627 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
@@ -1658,88 +1701,92 @@ acpi_video_bus_match(acpi_handle handle, u32 level, void *context, | |||
1658 | 1701 | ||
1659 | static void acpi_video_dev_register_backlight(struct acpi_video_device *device) | 1702 | static void acpi_video_dev_register_backlight(struct acpi_video_device *device) |
1660 | { | 1703 | { |
1661 | if (acpi_video_verify_backlight_support()) { | 1704 | struct backlight_properties props; |
1662 | struct backlight_properties props; | 1705 | struct pci_dev *pdev; |
1663 | struct pci_dev *pdev; | 1706 | acpi_handle acpi_parent; |
1664 | acpi_handle acpi_parent; | 1707 | struct device *parent = NULL; |
1665 | struct device *parent = NULL; | 1708 | int result; |
1666 | int result; | 1709 | static int count; |
1667 | static int count; | 1710 | char *name; |
1668 | char *name; | ||
1669 | |||
1670 | result = acpi_video_init_brightness(device); | ||
1671 | if (result) | ||
1672 | return; | ||
1673 | name = kasprintf(GFP_KERNEL, "acpi_video%d", count); | ||
1674 | if (!name) | ||
1675 | return; | ||
1676 | count++; | ||
1677 | 1711 | ||
1678 | acpi_get_parent(device->dev->handle, &acpi_parent); | 1712 | result = acpi_video_init_brightness(device); |
1713 | if (result) | ||
1714 | return; | ||
1715 | name = kasprintf(GFP_KERNEL, "acpi_video%d", count); | ||
1716 | if (!name) | ||
1717 | return; | ||
1718 | count++; | ||
1679 | 1719 | ||
1680 | pdev = acpi_get_pci_dev(acpi_parent); | 1720 | acpi_get_parent(device->dev->handle, &acpi_parent); |
1681 | if (pdev) { | ||
1682 | parent = &pdev->dev; | ||
1683 | pci_dev_put(pdev); | ||
1684 | } | ||
1685 | 1721 | ||
1686 | memset(&props, 0, sizeof(struct backlight_properties)); | 1722 | pdev = acpi_get_pci_dev(acpi_parent); |
1687 | props.type = BACKLIGHT_FIRMWARE; | 1723 | if (pdev) { |
1688 | props.max_brightness = device->brightness->count - 3; | 1724 | parent = &pdev->dev; |
1689 | device->backlight = backlight_device_register(name, | 1725 | pci_dev_put(pdev); |
1690 | parent, | 1726 | } |
1691 | device, | ||
1692 | &acpi_backlight_ops, | ||
1693 | &props); | ||
1694 | kfree(name); | ||
1695 | if (IS_ERR(device->backlight)) | ||
1696 | return; | ||
1697 | 1727 | ||
1698 | /* | 1728 | memset(&props, 0, sizeof(struct backlight_properties)); |
1699 | * Save current brightness level in case we have to restore it | 1729 | props.type = BACKLIGHT_FIRMWARE; |
1700 | * before acpi_video_device_lcd_set_level() is called next time. | 1730 | props.max_brightness = device->brightness->count - 3; |
1701 | */ | 1731 | device->backlight = backlight_device_register(name, |
1702 | device->backlight->props.brightness = | 1732 | parent, |
1703 | acpi_video_get_brightness(device->backlight); | 1733 | device, |
1734 | &acpi_backlight_ops, | ||
1735 | &props); | ||
1736 | kfree(name); | ||
1737 | if (IS_ERR(device->backlight)) | ||
1738 | return; | ||
1704 | 1739 | ||
1705 | device->cooling_dev = thermal_cooling_device_register("LCD", | 1740 | /* |
1706 | device->dev, &video_cooling_ops); | 1741 | * Save current brightness level in case we have to restore it |
1707 | if (IS_ERR(device->cooling_dev)) { | 1742 | * before acpi_video_device_lcd_set_level() is called next time. |
1708 | /* | 1743 | */ |
1709 | * Set cooling_dev to NULL so we don't crash trying to | 1744 | device->backlight->props.brightness = |
1710 | * free it. | 1745 | acpi_video_get_brightness(device->backlight); |
1711 | * Also, why the hell we are returning early and | ||
1712 | * not attempt to register video output if cooling | ||
1713 | * device registration failed? | ||
1714 | * -- dtor | ||
1715 | */ | ||
1716 | device->cooling_dev = NULL; | ||
1717 | return; | ||
1718 | } | ||
1719 | 1746 | ||
1720 | dev_info(&device->dev->dev, "registered as cooling_device%d\n", | 1747 | device->cooling_dev = thermal_cooling_device_register("LCD", |
1721 | device->cooling_dev->id); | 1748 | device->dev, &video_cooling_ops); |
1722 | result = sysfs_create_link(&device->dev->dev.kobj, | 1749 | if (IS_ERR(device->cooling_dev)) { |
1723 | &device->cooling_dev->device.kobj, | 1750 | /* |
1724 | "thermal_cooling"); | 1751 | * Set cooling_dev to NULL so we don't crash trying to free it. |
1725 | if (result) | 1752 | * Also, why the hell we are returning early and not attempt to |
1726 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 1753 | * register video output if cooling device registration failed? |
1727 | result = sysfs_create_link(&device->cooling_dev->device.kobj, | 1754 | * -- dtor |
1728 | &device->dev->dev.kobj, "device"); | 1755 | */ |
1729 | if (result) | 1756 | device->cooling_dev = NULL; |
1730 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 1757 | return; |
1731 | } | 1758 | } |
1759 | |||
1760 | dev_info(&device->dev->dev, "registered as cooling_device%d\n", | ||
1761 | device->cooling_dev->id); | ||
1762 | result = sysfs_create_link(&device->dev->dev.kobj, | ||
1763 | &device->cooling_dev->device.kobj, | ||
1764 | "thermal_cooling"); | ||
1765 | if (result) | ||
1766 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
1767 | result = sysfs_create_link(&device->cooling_dev->device.kobj, | ||
1768 | &device->dev->dev.kobj, "device"); | ||
1769 | if (result) | ||
1770 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
1732 | } | 1771 | } |
1733 | 1772 | ||
1734 | static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) | 1773 | static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) |
1735 | { | 1774 | { |
1736 | struct acpi_video_device *dev; | 1775 | struct acpi_video_device *dev; |
1737 | 1776 | ||
1777 | if (video->backlight_registered) | ||
1778 | return 0; | ||
1779 | |||
1780 | if (!acpi_video_verify_backlight_support()) | ||
1781 | return 0; | ||
1782 | |||
1738 | mutex_lock(&video->device_list_lock); | 1783 | mutex_lock(&video->device_list_lock); |
1739 | list_for_each_entry(dev, &video->video_device_list, entry) | 1784 | list_for_each_entry(dev, &video->video_device_list, entry) |
1740 | acpi_video_dev_register_backlight(dev); | 1785 | acpi_video_dev_register_backlight(dev); |
1741 | mutex_unlock(&video->device_list_lock); | 1786 | mutex_unlock(&video->device_list_lock); |
1742 | 1787 | ||
1788 | video->backlight_registered = true; | ||
1789 | |||
1743 | video->pm_nb.notifier_call = acpi_video_resume; | 1790 | video->pm_nb.notifier_call = acpi_video_resume; |
1744 | video->pm_nb.priority = 0; | 1791 | video->pm_nb.priority = 0; |
1745 | return register_pm_notifier(&video->pm_nb); | 1792 | return register_pm_notifier(&video->pm_nb); |
@@ -1767,13 +1814,20 @@ static void acpi_video_dev_unregister_backlight(struct acpi_video_device *device | |||
1767 | static int acpi_video_bus_unregister_backlight(struct acpi_video_bus *video) | 1814 | static int acpi_video_bus_unregister_backlight(struct acpi_video_bus *video) |
1768 | { | 1815 | { |
1769 | struct acpi_video_device *dev; | 1816 | struct acpi_video_device *dev; |
1770 | int error = unregister_pm_notifier(&video->pm_nb); | 1817 | int error; |
1818 | |||
1819 | if (!video->backlight_registered) | ||
1820 | return 0; | ||
1821 | |||
1822 | error = unregister_pm_notifier(&video->pm_nb); | ||
1771 | 1823 | ||
1772 | mutex_lock(&video->device_list_lock); | 1824 | mutex_lock(&video->device_list_lock); |
1773 | list_for_each_entry(dev, &video->video_device_list, entry) | 1825 | list_for_each_entry(dev, &video->video_device_list, entry) |
1774 | acpi_video_dev_unregister_backlight(dev); | 1826 | acpi_video_dev_unregister_backlight(dev); |
1775 | mutex_unlock(&video->device_list_lock); | 1827 | mutex_unlock(&video->device_list_lock); |
1776 | 1828 | ||
1829 | video->backlight_registered = false; | ||
1830 | |||
1777 | return error; | 1831 | return error; |
1778 | } | 1832 | } |
1779 | 1833 | ||
@@ -1867,6 +1921,56 @@ static void acpi_video_bus_remove_notify_handler(struct acpi_video_bus *video) | |||
1867 | video->input = NULL; | 1921 | video->input = NULL; |
1868 | } | 1922 | } |
1869 | 1923 | ||
1924 | static int acpi_video_backlight_notify(struct notifier_block *nb, | ||
1925 | unsigned long val, void *bd) | ||
1926 | { | ||
1927 | struct backlight_device *backlight = bd; | ||
1928 | struct acpi_video_bus *video; | ||
1929 | |||
1930 | /* acpi_video_verify_backlight_support only cares about raw devices */ | ||
1931 | if (backlight->props.type != BACKLIGHT_RAW) | ||
1932 | return NOTIFY_DONE; | ||
1933 | |||
1934 | video = container_of(nb, struct acpi_video_bus, backlight_nb); | ||
1935 | |||
1936 | switch (val) { | ||
1937 | case BACKLIGHT_REGISTERED: | ||
1938 | if (!acpi_video_verify_backlight_support()) | ||
1939 | acpi_video_bus_unregister_backlight(video); | ||
1940 | break; | ||
1941 | case BACKLIGHT_UNREGISTERED: | ||
1942 | acpi_video_bus_register_backlight(video); | ||
1943 | break; | ||
1944 | } | ||
1945 | |||
1946 | return NOTIFY_OK; | ||
1947 | } | ||
1948 | |||
1949 | static int acpi_video_bus_add_backlight_notify_handler( | ||
1950 | struct acpi_video_bus *video) | ||
1951 | { | ||
1952 | int error; | ||
1953 | |||
1954 | video->backlight_nb.notifier_call = acpi_video_backlight_notify; | ||
1955 | video->backlight_nb.priority = 0; | ||
1956 | error = backlight_register_notifier(&video->backlight_nb); | ||
1957 | if (error == 0) | ||
1958 | video->backlight_notifier_registered = true; | ||
1959 | |||
1960 | return error; | ||
1961 | } | ||
1962 | |||
1963 | static int acpi_video_bus_remove_backlight_notify_handler( | ||
1964 | struct acpi_video_bus *video) | ||
1965 | { | ||
1966 | if (!video->backlight_notifier_registered) | ||
1967 | return 0; | ||
1968 | |||
1969 | video->backlight_notifier_registered = false; | ||
1970 | |||
1971 | return backlight_unregister_notifier(&video->backlight_nb); | ||
1972 | } | ||
1973 | |||
1870 | static int acpi_video_bus_put_devices(struct acpi_video_bus *video) | 1974 | static int acpi_video_bus_put_devices(struct acpi_video_bus *video) |
1871 | { | 1975 | { |
1872 | struct acpi_video_device *dev, *next; | 1976 | struct acpi_video_device *dev, *next; |
@@ -1948,6 +2052,7 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
1948 | 2052 | ||
1949 | acpi_video_bus_register_backlight(video); | 2053 | acpi_video_bus_register_backlight(video); |
1950 | acpi_video_bus_add_notify_handler(video); | 2054 | acpi_video_bus_add_notify_handler(video); |
2055 | acpi_video_bus_add_backlight_notify_handler(video); | ||
1951 | 2056 | ||
1952 | return 0; | 2057 | return 0; |
1953 | 2058 | ||
@@ -1971,6 +2076,7 @@ static int acpi_video_bus_remove(struct acpi_device *device) | |||
1971 | 2076 | ||
1972 | video = acpi_driver_data(device); | 2077 | video = acpi_driver_data(device); |
1973 | 2078 | ||
2079 | acpi_video_bus_remove_backlight_notify_handler(video); | ||
1974 | acpi_video_bus_remove_notify_handler(video); | 2080 | acpi_video_bus_remove_notify_handler(video); |
1975 | acpi_video_bus_unregister_backlight(video); | 2081 | acpi_video_bus_unregister_backlight(video); |
1976 | acpi_video_bus_put_devices(video); | 2082 | acpi_video_bus_put_devices(video); |
@@ -2061,6 +2167,20 @@ void acpi_video_unregister(void) | |||
2061 | } | 2167 | } |
2062 | EXPORT_SYMBOL(acpi_video_unregister); | 2168 | EXPORT_SYMBOL(acpi_video_unregister); |
2063 | 2169 | ||
2170 | void acpi_video_unregister_backlight(void) | ||
2171 | { | ||
2172 | struct acpi_video_bus *video; | ||
2173 | |||
2174 | if (!register_count) | ||
2175 | return; | ||
2176 | |||
2177 | mutex_lock(&video_list_lock); | ||
2178 | list_for_each_entry(video, &video_bus_head, entry) | ||
2179 | acpi_video_bus_unregister_backlight(video); | ||
2180 | mutex_unlock(&video_list_lock); | ||
2181 | } | ||
2182 | EXPORT_SYMBOL(acpi_video_unregister_backlight); | ||
2183 | |||
2064 | /* | 2184 | /* |
2065 | * This is kind of nasty. Hardware using Intel chipsets may require | 2185 | * This is kind of nasty. Hardware using Intel chipsets may require |
2066 | * the video opregion code to be run first in order to initialise | 2186 | * the video opregion code to be run first in order to initialise |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 86d5e4fb5b98..343ffad59377 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -479,7 +479,7 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asyn | |||
479 | TRACE_DEVICE(dev); | 479 | TRACE_DEVICE(dev); |
480 | TRACE_RESUME(0); | 480 | TRACE_RESUME(0); |
481 | 481 | ||
482 | if (dev->power.syscore) | 482 | if (dev->power.syscore || dev->power.direct_complete) |
483 | goto Out; | 483 | goto Out; |
484 | 484 | ||
485 | if (!dev->power.is_noirq_suspended) | 485 | if (!dev->power.is_noirq_suspended) |
@@ -605,7 +605,7 @@ static int device_resume_early(struct device *dev, pm_message_t state, bool asyn | |||
605 | TRACE_DEVICE(dev); | 605 | TRACE_DEVICE(dev); |
606 | TRACE_RESUME(0); | 606 | TRACE_RESUME(0); |
607 | 607 | ||
608 | if (dev->power.syscore) | 608 | if (dev->power.syscore || dev->power.direct_complete) |
609 | goto Out; | 609 | goto Out; |
610 | 610 | ||
611 | if (!dev->power.is_late_suspended) | 611 | if (!dev->power.is_late_suspended) |
@@ -735,6 +735,12 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) | |||
735 | if (dev->power.syscore) | 735 | if (dev->power.syscore) |
736 | goto Complete; | 736 | goto Complete; |
737 | 737 | ||
738 | if (dev->power.direct_complete) { | ||
739 | /* Match the pm_runtime_disable() in __device_suspend(). */ | ||
740 | pm_runtime_enable(dev); | ||
741 | goto Complete; | ||
742 | } | ||
743 | |||
738 | dpm_wait(dev->parent, async); | 744 | dpm_wait(dev->parent, async); |
739 | dpm_watchdog_set(&wd, dev); | 745 | dpm_watchdog_set(&wd, dev); |
740 | device_lock(dev); | 746 | device_lock(dev); |
@@ -1007,7 +1013,7 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a | |||
1007 | goto Complete; | 1013 | goto Complete; |
1008 | } | 1014 | } |
1009 | 1015 | ||
1010 | if (dev->power.syscore) | 1016 | if (dev->power.syscore || dev->power.direct_complete) |
1011 | goto Complete; | 1017 | goto Complete; |
1012 | 1018 | ||
1013 | dpm_wait_for_children(dev, async); | 1019 | dpm_wait_for_children(dev, async); |
@@ -1146,7 +1152,7 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as | |||
1146 | goto Complete; | 1152 | goto Complete; |
1147 | } | 1153 | } |
1148 | 1154 | ||
1149 | if (dev->power.syscore) | 1155 | if (dev->power.syscore || dev->power.direct_complete) |
1150 | goto Complete; | 1156 | goto Complete; |
1151 | 1157 | ||
1152 | dpm_wait_for_children(dev, async); | 1158 | dpm_wait_for_children(dev, async); |
@@ -1332,6 +1338,17 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
1332 | if (dev->power.syscore) | 1338 | if (dev->power.syscore) |
1333 | goto Complete; | 1339 | goto Complete; |
1334 | 1340 | ||
1341 | if (dev->power.direct_complete) { | ||
1342 | if (pm_runtime_status_suspended(dev)) { | ||
1343 | pm_runtime_disable(dev); | ||
1344 | if (pm_runtime_suspended_if_enabled(dev)) | ||
1345 | goto Complete; | ||
1346 | |||
1347 | pm_runtime_enable(dev); | ||
1348 | } | ||
1349 | dev->power.direct_complete = false; | ||
1350 | } | ||
1351 | |||
1335 | dpm_watchdog_set(&wd, dev); | 1352 | dpm_watchdog_set(&wd, dev); |
1336 | device_lock(dev); | 1353 | device_lock(dev); |
1337 | 1354 | ||
@@ -1382,10 +1399,19 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
1382 | 1399 | ||
1383 | End: | 1400 | End: |
1384 | if (!error) { | 1401 | if (!error) { |
1402 | struct device *parent = dev->parent; | ||
1403 | |||
1385 | dev->power.is_suspended = true; | 1404 | dev->power.is_suspended = true; |
1386 | if (dev->power.wakeup_path | 1405 | if (parent) { |
1387 | && dev->parent && !dev->parent->power.ignore_children) | 1406 | spin_lock_irq(&parent->power.lock); |
1388 | dev->parent->power.wakeup_path = true; | 1407 | |
1408 | dev->parent->power.direct_complete = false; | ||
1409 | if (dev->power.wakeup_path | ||
1410 | && !dev->parent->power.ignore_children) | ||
1411 | dev->parent->power.wakeup_path = true; | ||
1412 | |||
1413 | spin_unlock_irq(&parent->power.lock); | ||
1414 | } | ||
1389 | } | 1415 | } |
1390 | 1416 | ||
1391 | device_unlock(dev); | 1417 | device_unlock(dev); |
@@ -1487,7 +1513,7 @@ static int device_prepare(struct device *dev, pm_message_t state) | |||
1487 | { | 1513 | { |
1488 | int (*callback)(struct device *) = NULL; | 1514 | int (*callback)(struct device *) = NULL; |
1489 | char *info = NULL; | 1515 | char *info = NULL; |
1490 | int error = 0; | 1516 | int ret = 0; |
1491 | 1517 | ||
1492 | if (dev->power.syscore) | 1518 | if (dev->power.syscore) |
1493 | return 0; | 1519 | return 0; |
@@ -1523,17 +1549,27 @@ static int device_prepare(struct device *dev, pm_message_t state) | |||
1523 | callback = dev->driver->pm->prepare; | 1549 | callback = dev->driver->pm->prepare; |
1524 | } | 1550 | } |
1525 | 1551 | ||
1526 | if (callback) { | 1552 | if (callback) |
1527 | error = callback(dev); | 1553 | ret = callback(dev); |
1528 | suspend_report_result(callback, error); | ||
1529 | } | ||
1530 | 1554 | ||
1531 | device_unlock(dev); | 1555 | device_unlock(dev); |
1532 | 1556 | ||
1533 | if (error) | 1557 | if (ret < 0) { |
1558 | suspend_report_result(callback, ret); | ||
1534 | pm_runtime_put(dev); | 1559 | pm_runtime_put(dev); |
1535 | 1560 | return ret; | |
1536 | return error; | 1561 | } |
1562 | /* | ||
1563 | * A positive return value from ->prepare() means "this device appears | ||
1564 | * to be runtime-suspended and its state is fine, so if it really is | ||
1565 | * runtime-suspended, you can leave it in that state provided that you | ||
1566 | * will do the same thing with all of its descendants". This only | ||
1567 | * applies to suspend transitions, however. | ||
1568 | */ | ||
1569 | spin_lock_irq(&dev->power.lock); | ||
1570 | dev->power.direct_complete = ret > 0 && state.event == PM_EVENT_SUSPEND; | ||
1571 | spin_unlock_irq(&dev->power.lock); | ||
1572 | return 0; | ||
1537 | } | 1573 | } |
1538 | 1574 | ||
1539 | /** | 1575 | /** |
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 25538675d59e..89ced955fafa 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/cpufreq.h> | ||
19 | #include <linux/device.h> | 18 | #include <linux/device.h> |
20 | #include <linux/list.h> | 19 | #include <linux/list.h> |
21 | #include <linux/rculist.h> | 20 | #include <linux/rculist.h> |
@@ -394,6 +393,13 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); | |||
394 | * to keep the integrity of the internal data structures. Callers should ensure | 393 | * to keep the integrity of the internal data structures. Callers should ensure |
395 | * that this function is *NOT* called under RCU protection or in contexts where | 394 | * that this function is *NOT* called under RCU protection or in contexts where |
396 | * mutex cannot be locked. | 395 | * mutex cannot be locked. |
396 | * | ||
397 | * Return: | ||
398 | * 0: On success OR | ||
399 | * Duplicate OPPs (both freq and volt are same) and opp->available | ||
400 | * -EEXIST: Freq are same and volt are different OR | ||
401 | * Duplicate OPPs (both freq and volt are same) and !opp->available | ||
402 | * -ENOMEM: Memory allocation failure | ||
397 | */ | 403 | */ |
398 | int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) | 404 | int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) |
399 | { | 405 | { |
@@ -443,15 +449,31 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) | |||
443 | new_opp->u_volt = u_volt; | 449 | new_opp->u_volt = u_volt; |
444 | new_opp->available = true; | 450 | new_opp->available = true; |
445 | 451 | ||
446 | /* Insert new OPP in order of increasing frequency */ | 452 | /* |
453 | * Insert new OPP in order of increasing frequency | ||
454 | * and discard if already present | ||
455 | */ | ||
447 | head = &dev_opp->opp_list; | 456 | head = &dev_opp->opp_list; |
448 | list_for_each_entry_rcu(opp, &dev_opp->opp_list, node) { | 457 | list_for_each_entry_rcu(opp, &dev_opp->opp_list, node) { |
449 | if (new_opp->rate < opp->rate) | 458 | if (new_opp->rate <= opp->rate) |
450 | break; | 459 | break; |
451 | else | 460 | else |
452 | head = &opp->node; | 461 | head = &opp->node; |
453 | } | 462 | } |
454 | 463 | ||
464 | /* Duplicate OPPs ? */ | ||
465 | if (new_opp->rate == opp->rate) { | ||
466 | int ret = opp->available && new_opp->u_volt == opp->u_volt ? | ||
467 | 0 : -EEXIST; | ||
468 | |||
469 | dev_warn(dev, "%s: duplicate OPPs detected. Existing: freq: %lu, volt: %lu, enabled: %d. New: freq: %lu, volt: %lu, enabled: %d\n", | ||
470 | __func__, opp->rate, opp->u_volt, opp->available, | ||
471 | new_opp->rate, new_opp->u_volt, new_opp->available); | ||
472 | mutex_unlock(&dev_opp_list_lock); | ||
473 | kfree(new_opp); | ||
474 | return ret; | ||
475 | } | ||
476 | |||
455 | list_add_rcu(&new_opp->node, head); | 477 | list_add_rcu(&new_opp->node, head); |
456 | mutex_unlock(&dev_opp_list_lock); | 478 | mutex_unlock(&dev_opp_list_lock); |
457 | 479 | ||
@@ -596,96 +618,6 @@ int dev_pm_opp_disable(struct device *dev, unsigned long freq) | |||
596 | } | 618 | } |
597 | EXPORT_SYMBOL_GPL(dev_pm_opp_disable); | 619 | EXPORT_SYMBOL_GPL(dev_pm_opp_disable); |
598 | 620 | ||
599 | #ifdef CONFIG_CPU_FREQ | ||
600 | /** | ||
601 | * dev_pm_opp_init_cpufreq_table() - create a cpufreq table for a device | ||
602 | * @dev: device for which we do this operation | ||
603 | * @table: Cpufreq table returned back to caller | ||
604 | * | ||
605 | * Generate a cpufreq table for a provided device- this assumes that the | ||
606 | * opp list is already initialized and ready for usage. | ||
607 | * | ||
608 | * This function allocates required memory for the cpufreq table. It is | ||
609 | * expected that the caller does the required maintenance such as freeing | ||
610 | * the table as required. | ||
611 | * | ||
612 | * Returns -EINVAL for bad pointers, -ENODEV if the device is not found, -ENOMEM | ||
613 | * if no memory available for the operation (table is not populated), returns 0 | ||
614 | * if successful and table is populated. | ||
615 | * | ||
616 | * WARNING: It is important for the callers to ensure refreshing their copy of | ||
617 | * the table if any of the mentioned functions have been invoked in the interim. | ||
618 | * | ||
619 | * Locking: The internal device_opp and opp structures are RCU protected. | ||
620 | * To simplify the logic, we pretend we are updater and hold relevant mutex here | ||
621 | * Callers should ensure that this function is *NOT* called under RCU protection | ||
622 | * or in contexts where mutex locking cannot be used. | ||
623 | */ | ||
624 | int dev_pm_opp_init_cpufreq_table(struct device *dev, | ||
625 | struct cpufreq_frequency_table **table) | ||
626 | { | ||
627 | struct device_opp *dev_opp; | ||
628 | struct dev_pm_opp *opp; | ||
629 | struct cpufreq_frequency_table *freq_table; | ||
630 | int i = 0; | ||
631 | |||
632 | /* Pretend as if I am an updater */ | ||
633 | mutex_lock(&dev_opp_list_lock); | ||
634 | |||
635 | dev_opp = find_device_opp(dev); | ||
636 | if (IS_ERR(dev_opp)) { | ||
637 | int r = PTR_ERR(dev_opp); | ||
638 | mutex_unlock(&dev_opp_list_lock); | ||
639 | dev_err(dev, "%s: Device OPP not found (%d)\n", __func__, r); | ||
640 | return r; | ||
641 | } | ||
642 | |||
643 | freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * | ||
644 | (dev_pm_opp_get_opp_count(dev) + 1), GFP_KERNEL); | ||
645 | if (!freq_table) { | ||
646 | mutex_unlock(&dev_opp_list_lock); | ||
647 | dev_warn(dev, "%s: Unable to allocate frequency table\n", | ||
648 | __func__); | ||
649 | return -ENOMEM; | ||
650 | } | ||
651 | |||
652 | list_for_each_entry(opp, &dev_opp->opp_list, node) { | ||
653 | if (opp->available) { | ||
654 | freq_table[i].driver_data = i; | ||
655 | freq_table[i].frequency = opp->rate / 1000; | ||
656 | i++; | ||
657 | } | ||
658 | } | ||
659 | mutex_unlock(&dev_opp_list_lock); | ||
660 | |||
661 | freq_table[i].driver_data = i; | ||
662 | freq_table[i].frequency = CPUFREQ_TABLE_END; | ||
663 | |||
664 | *table = &freq_table[0]; | ||
665 | |||
666 | return 0; | ||
667 | } | ||
668 | EXPORT_SYMBOL_GPL(dev_pm_opp_init_cpufreq_table); | ||
669 | |||
670 | /** | ||
671 | * dev_pm_opp_free_cpufreq_table() - free the cpufreq table | ||
672 | * @dev: device for which we do this operation | ||
673 | * @table: table to free | ||
674 | * | ||
675 | * Free up the table allocated by dev_pm_opp_init_cpufreq_table | ||
676 | */ | ||
677 | void dev_pm_opp_free_cpufreq_table(struct device *dev, | ||
678 | struct cpufreq_frequency_table **table) | ||
679 | { | ||
680 | if (!table) | ||
681 | return; | ||
682 | |||
683 | kfree(*table); | ||
684 | *table = NULL; | ||
685 | } | ||
686 | EXPORT_SYMBOL_GPL(dev_pm_opp_free_cpufreq_table); | ||
687 | #endif /* CONFIG_CPU_FREQ */ | ||
688 | |||
689 | /** | 621 | /** |
690 | * dev_pm_opp_get_notifier() - find notifier_head of the device with opp | 622 | * dev_pm_opp_get_notifier() - find notifier_head of the device with opp |
691 | * @dev: device pointer used to lookup device OPPs. | 623 | * @dev: device pointer used to lookup device OPPs. |
@@ -734,11 +666,9 @@ int of_init_opp_table(struct device *dev) | |||
734 | unsigned long freq = be32_to_cpup(val++) * 1000; | 666 | unsigned long freq = be32_to_cpup(val++) * 1000; |
735 | unsigned long volt = be32_to_cpup(val++); | 667 | unsigned long volt = be32_to_cpup(val++); |
736 | 668 | ||
737 | if (dev_pm_opp_add(dev, freq, volt)) { | 669 | if (dev_pm_opp_add(dev, freq, volt)) |
738 | dev_warn(dev, "%s: Failed to add OPP %ld\n", | 670 | dev_warn(dev, "%s: Failed to add OPP %ld\n", |
739 | __func__, freq); | 671 | __func__, freq); |
740 | continue; | ||
741 | } | ||
742 | nr -= 2; | 672 | nr -= 2; |
743 | } | 673 | } |
744 | 674 | ||
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 2d56f4113ae7..eb1bd2ecad8b 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c | |||
@@ -318,10 +318,16 @@ int device_init_wakeup(struct device *dev, bool enable) | |||
318 | { | 318 | { |
319 | int ret = 0; | 319 | int ret = 0; |
320 | 320 | ||
321 | if (!dev) | ||
322 | return -EINVAL; | ||
323 | |||
321 | if (enable) { | 324 | if (enable) { |
322 | device_set_wakeup_capable(dev, true); | 325 | device_set_wakeup_capable(dev, true); |
323 | ret = device_wakeup_enable(dev); | 326 | ret = device_wakeup_enable(dev); |
324 | } else { | 327 | } else { |
328 | if (dev->power.can_wakeup) | ||
329 | device_wakeup_disable(dev); | ||
330 | |||
325 | device_set_wakeup_capable(dev, false); | 331 | device_set_wakeup_capable(dev, false); |
326 | } | 332 | } |
327 | 333 | ||
diff --git a/drivers/char/tpm/tpm_acpi.c b/drivers/char/tpm/tpm_acpi.c index b9a57fa4b710..565a9478cb94 100644 --- a/drivers/char/tpm/tpm_acpi.c +++ b/drivers/char/tpm/tpm_acpi.c | |||
@@ -95,7 +95,7 @@ int read_log(struct tpm_bios_log *log) | |||
95 | 95 | ||
96 | log->bios_event_log_end = log->bios_event_log + len; | 96 | log->bios_event_log_end = log->bios_event_log + len; |
97 | 97 | ||
98 | virt = acpi_os_map_memory(start, len); | 98 | virt = acpi_os_map_iomem(start, len); |
99 | if (!virt) { | 99 | if (!virt) { |
100 | kfree(log->bios_event_log); | 100 | kfree(log->bios_event_log); |
101 | printk("%s: ERROR - Unable to map memory\n", __func__); | 101 | printk("%s: ERROR - Unable to map memory\n", __func__); |
@@ -104,6 +104,6 @@ int read_log(struct tpm_bios_log *log) | |||
104 | 104 | ||
105 | memcpy_fromio(log->bios_event_log, virt, len); | 105 | memcpy_fromio(log->bios_event_log, virt, len); |
106 | 106 | ||
107 | acpi_os_unmap_memory(virt, len); | 107 | acpi_os_unmap_iomem(virt, len); |
108 | return 0; | 108 | return 0; |
109 | } | 109 | } |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 17d7f13d19a5..50b2a7ebd747 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-fixed-rate.o | |||
8 | obj-$(CONFIG_COMMON_CLK) += clk-gate.o | 8 | obj-$(CONFIG_COMMON_CLK) += clk-gate.o |
9 | obj-$(CONFIG_COMMON_CLK) += clk-mux.o | 9 | obj-$(CONFIG_COMMON_CLK) += clk-mux.o |
10 | obj-$(CONFIG_COMMON_CLK) += clk-composite.o | 10 | obj-$(CONFIG_COMMON_CLK) += clk-composite.o |
11 | obj-$(CONFIG_COMMON_CLK) += clk-fractional-divider.o | ||
11 | 12 | ||
12 | # hardware specific clock types | 13 | # hardware specific clock types |
13 | # please keep this section sorted lexicographically by file/directory path name | 14 | # please keep this section sorted lexicographically by file/directory path name |
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c new file mode 100644 index 000000000000..ede685ca0d20 --- /dev/null +++ b/drivers/clk/clk-fractional-divider.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Intel Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * Adjustable fractional divider clock implementation. | ||
9 | * Output rate = (m / n) * parent_rate. | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk-provider.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <linux/gcd.h> | ||
17 | |||
18 | #define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) | ||
19 | |||
20 | static unsigned long clk_fd_recalc_rate(struct clk_hw *hw, | ||
21 | unsigned long parent_rate) | ||
22 | { | ||
23 | struct clk_fractional_divider *fd = to_clk_fd(hw); | ||
24 | unsigned long flags = 0; | ||
25 | u32 val, m, n; | ||
26 | u64 ret; | ||
27 | |||
28 | if (fd->lock) | ||
29 | spin_lock_irqsave(fd->lock, flags); | ||
30 | |||
31 | val = clk_readl(fd->reg); | ||
32 | |||
33 | if (fd->lock) | ||
34 | spin_unlock_irqrestore(fd->lock, flags); | ||
35 | |||
36 | m = (val & fd->mmask) >> fd->mshift; | ||
37 | n = (val & fd->nmask) >> fd->nshift; | ||
38 | |||
39 | ret = parent_rate * m; | ||
40 | do_div(ret, n); | ||
41 | |||
42 | return ret; | ||
43 | } | ||
44 | |||
45 | static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate, | ||
46 | unsigned long *prate) | ||
47 | { | ||
48 | struct clk_fractional_divider *fd = to_clk_fd(hw); | ||
49 | unsigned maxn = (fd->nmask >> fd->nshift) + 1; | ||
50 | unsigned div; | ||
51 | |||
52 | if (!rate || rate >= *prate) | ||
53 | return *prate; | ||
54 | |||
55 | div = gcd(*prate, rate); | ||
56 | |||
57 | while ((*prate / div) > maxn) { | ||
58 | div <<= 1; | ||
59 | rate <<= 1; | ||
60 | } | ||
61 | |||
62 | return rate; | ||
63 | } | ||
64 | |||
65 | static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate, | ||
66 | unsigned long parent_rate) | ||
67 | { | ||
68 | struct clk_fractional_divider *fd = to_clk_fd(hw); | ||
69 | unsigned long flags = 0; | ||
70 | unsigned long div; | ||
71 | unsigned n, m; | ||
72 | u32 val; | ||
73 | |||
74 | div = gcd(parent_rate, rate); | ||
75 | m = rate / div; | ||
76 | n = parent_rate / div; | ||
77 | |||
78 | if (fd->lock) | ||
79 | spin_lock_irqsave(fd->lock, flags); | ||
80 | |||
81 | val = clk_readl(fd->reg); | ||
82 | val &= ~(fd->mmask | fd->nmask); | ||
83 | val |= (m << fd->mshift) | (n << fd->nshift); | ||
84 | clk_writel(val, fd->reg); | ||
85 | |||
86 | if (fd->lock) | ||
87 | spin_unlock_irqrestore(fd->lock, flags); | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | const struct clk_ops clk_fractional_divider_ops = { | ||
93 | .recalc_rate = clk_fd_recalc_rate, | ||
94 | .round_rate = clk_fd_round_rate, | ||
95 | .set_rate = clk_fd_set_rate, | ||
96 | }; | ||
97 | EXPORT_SYMBOL_GPL(clk_fractional_divider_ops); | ||
98 | |||
99 | struct clk *clk_register_fractional_divider(struct device *dev, | ||
100 | const char *name, const char *parent_name, unsigned long flags, | ||
101 | void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth, | ||
102 | u8 clk_divider_flags, spinlock_t *lock) | ||
103 | { | ||
104 | struct clk_fractional_divider *fd; | ||
105 | struct clk_init_data init; | ||
106 | struct clk *clk; | ||
107 | |||
108 | fd = kzalloc(sizeof(*fd), GFP_KERNEL); | ||
109 | if (!fd) { | ||
110 | dev_err(dev, "could not allocate fractional divider clk\n"); | ||
111 | return ERR_PTR(-ENOMEM); | ||
112 | } | ||
113 | |||
114 | init.name = name; | ||
115 | init.ops = &clk_fractional_divider_ops; | ||
116 | init.flags = flags | CLK_IS_BASIC; | ||
117 | init.parent_names = parent_name ? &parent_name : NULL; | ||
118 | init.num_parents = parent_name ? 1 : 0; | ||
119 | |||
120 | fd->reg = reg; | ||
121 | fd->mshift = mshift; | ||
122 | fd->mmask = (BIT(mwidth) - 1) << mshift; | ||
123 | fd->nshift = nshift; | ||
124 | fd->nmask = (BIT(nwidth) - 1) << nshift; | ||
125 | fd->flags = clk_divider_flags; | ||
126 | fd->lock = lock; | ||
127 | fd->hw.init = &init; | ||
128 | |||
129 | clk = clk_register(dev, &fd->hw); | ||
130 | if (IS_ERR(clk)) | ||
131 | kfree(fd); | ||
132 | |||
133 | return clk; | ||
134 | } | ||
135 | EXPORT_SYMBOL_GPL(clk_register_fractional_divider); | ||
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index d2c7b4b8ffd5..36d20d0fce27 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm | |||
@@ -5,7 +5,8 @@ | |||
5 | # big LITTLE core layer and glue drivers | 5 | # big LITTLE core layer and glue drivers |
6 | config ARM_BIG_LITTLE_CPUFREQ | 6 | config ARM_BIG_LITTLE_CPUFREQ |
7 | tristate "Generic ARM big LITTLE CPUfreq driver" | 7 | tristate "Generic ARM big LITTLE CPUfreq driver" |
8 | depends on ARM && BIG_LITTLE && ARM_CPU_TOPOLOGY && HAVE_CLK | 8 | depends on (BIG_LITTLE && ARM_CPU_TOPOLOGY) || (ARM64 && SMP) |
9 | depends on HAVE_CLK | ||
9 | select PM_OPP | 10 | select PM_OPP |
10 | help | 11 | help |
11 | This enables the Generic CPUfreq driver for ARM big.LITTLE platforms. | 12 | This enables the Generic CPUfreq driver for ARM big.LITTLE platforms. |
@@ -85,7 +86,7 @@ config ARM_EXYNOS_CPU_FREQ_BOOST_SW | |||
85 | It allows usage of special frequencies for Samsung Exynos | 86 | It allows usage of special frequencies for Samsung Exynos |
86 | processors if thermal conditions are appropriate. | 87 | processors if thermal conditions are appropriate. |
87 | 88 | ||
88 | It reguires, for safe operation, thermal framework with properly | 89 | It requires, for safe operation, thermal framework with properly |
89 | defined trip points. | 90 | defined trip points. |
90 | 91 | ||
91 | If in doubt, say N. | 92 | If in doubt, say N. |
@@ -186,7 +187,7 @@ config ARM_S3C2416_CPUFREQ | |||
186 | S3C2450 SoC. The S3C2416 supports changing the rate of the | 187 | S3C2450 SoC. The S3C2416 supports changing the rate of the |
187 | armdiv clock source and also entering a so called dynamic | 188 | armdiv clock source and also entering a so called dynamic |
188 | voltage scaling mode in which it is possible to reduce the | 189 | voltage scaling mode in which it is possible to reduce the |
189 | core voltage of the cpu. | 190 | core voltage of the CPU. |
190 | 191 | ||
191 | If in doubt, say N. | 192 | If in doubt, say N. |
192 | 193 | ||
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 index d369349eeaab..89ae88f91895 100644 --- a/drivers/cpufreq/Kconfig.x86 +++ b/drivers/cpufreq/Kconfig.x86 | |||
@@ -10,7 +10,7 @@ config X86_INTEL_PSTATE | |||
10 | The driver implements an internal governor and will become | 10 | The driver implements an internal governor and will become |
11 | the scaling driver and governor for Sandy bridge processors. | 11 | the scaling driver and governor for Sandy bridge processors. |
12 | 12 | ||
13 | When this driver is enabled it will become the perferred | 13 | When this driver is enabled it will become the preferred |
14 | scaling driver for Sandy bridge processors. | 14 | scaling driver for Sandy bridge processors. |
15 | 15 | ||
16 | If in doubt, say N. | 16 | If in doubt, say N. |
@@ -52,7 +52,7 @@ config X86_ACPI_CPUFREQ_CPB | |||
52 | help | 52 | help |
53 | The powernow-k8 driver used to provide a sysfs knob called "cpb" | 53 | The powernow-k8 driver used to provide a sysfs knob called "cpb" |
54 | to disable the Core Performance Boosting feature of AMD CPUs. This | 54 | to disable the Core Performance Boosting feature of AMD CPUs. This |
55 | file has now been superseeded by the more generic "boost" entry. | 55 | file has now been superseded by the more generic "boost" entry. |
56 | 56 | ||
57 | By enabling this option the acpi_cpufreq driver provides the old | 57 | By enabling this option the acpi_cpufreq driver provides the old |
58 | entry in addition to the new boost ones, for compatibility reasons. | 58 | entry in addition to the new boost ones, for compatibility reasons. |
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 0dbb963c1aef..738c8b7b17dc 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile | |||
@@ -1,5 +1,7 @@ | |||
1 | # CPUfreq core | 1 | # CPUfreq core |
2 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o freq_table.o | 2 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o freq_table.o |
3 | obj-$(CONFIG_PM_OPP) += cpufreq_opp.o | ||
4 | |||
3 | # CPUfreq stats | 5 | # CPUfreq stats |
4 | obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o | 6 | obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o |
5 | 7 | ||
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 000e4e0afd7e..b0c18ed8d83f 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
@@ -213,7 +213,7 @@ static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data) | |||
213 | 213 | ||
214 | static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data) | 214 | static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data) |
215 | { | 215 | { |
216 | int i; | 216 | struct cpufreq_frequency_table *pos; |
217 | struct acpi_processor_performance *perf; | 217 | struct acpi_processor_performance *perf; |
218 | 218 | ||
219 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) | 219 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) |
@@ -223,10 +223,9 @@ static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data) | |||
223 | 223 | ||
224 | perf = data->acpi_data; | 224 | perf = data->acpi_data; |
225 | 225 | ||
226 | for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { | 226 | cpufreq_for_each_entry(pos, data->freq_table) |
227 | if (msr == perf->states[data->freq_table[i].driver_data].status) | 227 | if (msr == perf->states[pos->driver_data].status) |
228 | return data->freq_table[i].frequency; | 228 | return pos->frequency; |
229 | } | ||
230 | return data->freq_table[0].frequency; | 229 | return data->freq_table[0].frequency; |
231 | } | 230 | } |
232 | 231 | ||
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index bad2ed317ba2..1f4d4e315057 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c | |||
@@ -226,22 +226,22 @@ static inline u32 get_table_count(struct cpufreq_frequency_table *table) | |||
226 | /* get the minimum frequency in the cpufreq_frequency_table */ | 226 | /* get the minimum frequency in the cpufreq_frequency_table */ |
227 | static inline u32 get_table_min(struct cpufreq_frequency_table *table) | 227 | static inline u32 get_table_min(struct cpufreq_frequency_table *table) |
228 | { | 228 | { |
229 | int i; | 229 | struct cpufreq_frequency_table *pos; |
230 | uint32_t min_freq = ~0; | 230 | uint32_t min_freq = ~0; |
231 | for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) | 231 | cpufreq_for_each_entry(pos, table) |
232 | if (table[i].frequency < min_freq) | 232 | if (pos->frequency < min_freq) |
233 | min_freq = table[i].frequency; | 233 | min_freq = pos->frequency; |
234 | return min_freq; | 234 | return min_freq; |
235 | } | 235 | } |
236 | 236 | ||
237 | /* get the maximum frequency in the cpufreq_frequency_table */ | 237 | /* get the maximum frequency in the cpufreq_frequency_table */ |
238 | static inline u32 get_table_max(struct cpufreq_frequency_table *table) | 238 | static inline u32 get_table_max(struct cpufreq_frequency_table *table) |
239 | { | 239 | { |
240 | int i; | 240 | struct cpufreq_frequency_table *pos; |
241 | uint32_t max_freq = 0; | 241 | uint32_t max_freq = 0; |
242 | for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) | 242 | cpufreq_for_each_entry(pos, table) |
243 | if (table[i].frequency > max_freq) | 243 | if (pos->frequency > max_freq) |
244 | max_freq = table[i].frequency; | 244 | max_freq = pos->frequency; |
245 | return max_freq; | 245 | return max_freq; |
246 | } | 246 | } |
247 | 247 | ||
diff --git a/drivers/cpufreq/cpufreq-nforce2.c b/drivers/cpufreq/cpufreq-nforce2.c index bc447b9003c3..a2258090b58b 100644 --- a/drivers/cpufreq/cpufreq-nforce2.c +++ b/drivers/cpufreq/cpufreq-nforce2.c | |||
@@ -379,7 +379,7 @@ static struct cpufreq_driver nforce2_driver = { | |||
379 | }; | 379 | }; |
380 | 380 | ||
381 | #ifdef MODULE | 381 | #ifdef MODULE |
382 | static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = { | 382 | static const struct pci_device_id nforce2_ids[] = { |
383 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2 }, | 383 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2 }, |
384 | {} | 384 | {} |
385 | }; | 385 | }; |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index abda6609d3e7..ae11dd51f81d 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -354,6 +354,18 @@ static void cpufreq_notify_post_transition(struct cpufreq_policy *policy, | |||
354 | void cpufreq_freq_transition_begin(struct cpufreq_policy *policy, | 354 | void cpufreq_freq_transition_begin(struct cpufreq_policy *policy, |
355 | struct cpufreq_freqs *freqs) | 355 | struct cpufreq_freqs *freqs) |
356 | { | 356 | { |
357 | |||
358 | /* | ||
359 | * Catch double invocations of _begin() which lead to self-deadlock. | ||
360 | * ASYNC_NOTIFICATION drivers are left out because the cpufreq core | ||
361 | * doesn't invoke _begin() on their behalf, and hence the chances of | ||
362 | * double invocations are very low. Moreover, there are scenarios | ||
363 | * where these checks can emit false-positive warnings in these | ||
364 | * drivers; so we avoid that by skipping them altogether. | ||
365 | */ | ||
366 | WARN_ON(!(cpufreq_driver->flags & CPUFREQ_ASYNC_NOTIFICATION) | ||
367 | && current == policy->transition_task); | ||
368 | |||
357 | wait: | 369 | wait: |
358 | wait_event(policy->transition_wait, !policy->transition_ongoing); | 370 | wait_event(policy->transition_wait, !policy->transition_ongoing); |
359 | 371 | ||
@@ -365,6 +377,7 @@ wait: | |||
365 | } | 377 | } |
366 | 378 | ||
367 | policy->transition_ongoing = true; | 379 | policy->transition_ongoing = true; |
380 | policy->transition_task = current; | ||
368 | 381 | ||
369 | spin_unlock(&policy->transition_lock); | 382 | spin_unlock(&policy->transition_lock); |
370 | 383 | ||
@@ -381,6 +394,7 @@ void cpufreq_freq_transition_end(struct cpufreq_policy *policy, | |||
381 | cpufreq_notify_post_transition(policy, freqs, transition_failed); | 394 | cpufreq_notify_post_transition(policy, freqs, transition_failed); |
382 | 395 | ||
383 | policy->transition_ongoing = false; | 396 | policy->transition_ongoing = false; |
397 | policy->transition_task = NULL; | ||
384 | 398 | ||
385 | wake_up(&policy->transition_wait); | 399 | wake_up(&policy->transition_wait); |
386 | } | 400 | } |
@@ -1802,12 +1816,43 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier); | |||
1802 | * GOVERNORS * | 1816 | * GOVERNORS * |
1803 | *********************************************************************/ | 1817 | *********************************************************************/ |
1804 | 1818 | ||
1819 | static int __target_index(struct cpufreq_policy *policy, | ||
1820 | struct cpufreq_frequency_table *freq_table, int index) | ||
1821 | { | ||
1822 | struct cpufreq_freqs freqs; | ||
1823 | int retval = -EINVAL; | ||
1824 | bool notify; | ||
1825 | |||
1826 | notify = !(cpufreq_driver->flags & CPUFREQ_ASYNC_NOTIFICATION); | ||
1827 | |||
1828 | if (notify) { | ||
1829 | freqs.old = policy->cur; | ||
1830 | freqs.new = freq_table[index].frequency; | ||
1831 | freqs.flags = 0; | ||
1832 | |||
1833 | pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n", | ||
1834 | __func__, policy->cpu, freqs.old, freqs.new); | ||
1835 | |||
1836 | cpufreq_freq_transition_begin(policy, &freqs); | ||
1837 | } | ||
1838 | |||
1839 | retval = cpufreq_driver->target_index(policy, index); | ||
1840 | if (retval) | ||
1841 | pr_err("%s: Failed to change cpu frequency: %d\n", __func__, | ||
1842 | retval); | ||
1843 | |||
1844 | if (notify) | ||
1845 | cpufreq_freq_transition_end(policy, &freqs, retval); | ||
1846 | |||
1847 | return retval; | ||
1848 | } | ||
1849 | |||
1805 | int __cpufreq_driver_target(struct cpufreq_policy *policy, | 1850 | int __cpufreq_driver_target(struct cpufreq_policy *policy, |
1806 | unsigned int target_freq, | 1851 | unsigned int target_freq, |
1807 | unsigned int relation) | 1852 | unsigned int relation) |
1808 | { | 1853 | { |
1809 | int retval = -EINVAL; | ||
1810 | unsigned int old_target_freq = target_freq; | 1854 | unsigned int old_target_freq = target_freq; |
1855 | int retval = -EINVAL; | ||
1811 | 1856 | ||
1812 | if (cpufreq_disabled()) | 1857 | if (cpufreq_disabled()) |
1813 | return -ENODEV; | 1858 | return -ENODEV; |
@@ -1834,8 +1879,6 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, | |||
1834 | retval = cpufreq_driver->target(policy, target_freq, relation); | 1879 | retval = cpufreq_driver->target(policy, target_freq, relation); |
1835 | else if (cpufreq_driver->target_index) { | 1880 | else if (cpufreq_driver->target_index) { |
1836 | struct cpufreq_frequency_table *freq_table; | 1881 | struct cpufreq_frequency_table *freq_table; |
1837 | struct cpufreq_freqs freqs; | ||
1838 | bool notify; | ||
1839 | int index; | 1882 | int index; |
1840 | 1883 | ||
1841 | freq_table = cpufreq_frequency_get_table(policy->cpu); | 1884 | freq_table = cpufreq_frequency_get_table(policy->cpu); |
@@ -1856,26 +1899,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, | |||
1856 | goto out; | 1899 | goto out; |
1857 | } | 1900 | } |
1858 | 1901 | ||
1859 | notify = !(cpufreq_driver->flags & CPUFREQ_ASYNC_NOTIFICATION); | 1902 | retval = __target_index(policy, freq_table, index); |
1860 | |||
1861 | if (notify) { | ||
1862 | freqs.old = policy->cur; | ||
1863 | freqs.new = freq_table[index].frequency; | ||
1864 | freqs.flags = 0; | ||
1865 | |||
1866 | pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n", | ||
1867 | __func__, policy->cpu, freqs.old, freqs.new); | ||
1868 | |||
1869 | cpufreq_freq_transition_begin(policy, &freqs); | ||
1870 | } | ||
1871 | |||
1872 | retval = cpufreq_driver->target_index(policy, index); | ||
1873 | if (retval) | ||
1874 | pr_err("%s: Failed to change cpu frequency: %d\n", | ||
1875 | __func__, retval); | ||
1876 | |||
1877 | if (notify) | ||
1878 | cpufreq_freq_transition_end(policy, &freqs, retval); | ||
1879 | } | 1903 | } |
1880 | 1904 | ||
1881 | out: | 1905 | out: |
diff --git a/drivers/cpufreq/cpufreq_opp.c b/drivers/cpufreq/cpufreq_opp.c new file mode 100644 index 000000000000..c0c6f4a4eccf --- /dev/null +++ b/drivers/cpufreq/cpufreq_opp.c | |||
@@ -0,0 +1,110 @@ | |||
1 | /* | ||
2 | * Generic OPP helper interface for CPUFreq drivers | ||
3 | * | ||
4 | * Copyright (C) 2009-2014 Texas Instruments Incorporated. | ||
5 | * Nishanth Menon | ||
6 | * Romit Dasgupta | ||
7 | * Kevin Hilman | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | #include <linux/cpufreq.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/export.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/pm_opp.h> | ||
20 | #include <linux/rcupdate.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | /** | ||
24 | * dev_pm_opp_init_cpufreq_table() - create a cpufreq table for a device | ||
25 | * @dev: device for which we do this operation | ||
26 | * @table: Cpufreq table returned back to caller | ||
27 | * | ||
28 | * Generate a cpufreq table for a provided device- this assumes that the | ||
29 | * opp list is already initialized and ready for usage. | ||
30 | * | ||
31 | * This function allocates required memory for the cpufreq table. It is | ||
32 | * expected that the caller does the required maintenance such as freeing | ||
33 | * the table as required. | ||
34 | * | ||
35 | * Returns -EINVAL for bad pointers, -ENODEV if the device is not found, -ENOMEM | ||
36 | * if no memory available for the operation (table is not populated), returns 0 | ||
37 | * if successful and table is populated. | ||
38 | * | ||
39 | * WARNING: It is important for the callers to ensure refreshing their copy of | ||
40 | * the table if any of the mentioned functions have been invoked in the interim. | ||
41 | * | ||
42 | * Locking: The internal device_opp and opp structures are RCU protected. | ||
43 | * Since we just use the regular accessor functions to access the internal data | ||
44 | * structures, we use RCU read lock inside this function. As a result, users of | ||
45 | * this function DONOT need to use explicit locks for invoking. | ||
46 | */ | ||
47 | int dev_pm_opp_init_cpufreq_table(struct device *dev, | ||
48 | struct cpufreq_frequency_table **table) | ||
49 | { | ||
50 | struct dev_pm_opp *opp; | ||
51 | struct cpufreq_frequency_table *freq_table = NULL; | ||
52 | int i, max_opps, ret = 0; | ||
53 | unsigned long rate; | ||
54 | |||
55 | rcu_read_lock(); | ||
56 | |||
57 | max_opps = dev_pm_opp_get_opp_count(dev); | ||
58 | if (max_opps <= 0) { | ||
59 | ret = max_opps ? max_opps : -ENODATA; | ||
60 | goto out; | ||
61 | } | ||
62 | |||
63 | freq_table = kzalloc(sizeof(*freq_table) * (max_opps + 1), GFP_KERNEL); | ||
64 | if (!freq_table) { | ||
65 | ret = -ENOMEM; | ||
66 | goto out; | ||
67 | } | ||
68 | |||
69 | for (i = 0, rate = 0; i < max_opps; i++, rate++) { | ||
70 | /* find next rate */ | ||
71 | opp = dev_pm_opp_find_freq_ceil(dev, &rate); | ||
72 | if (IS_ERR(opp)) { | ||
73 | ret = PTR_ERR(opp); | ||
74 | goto out; | ||
75 | } | ||
76 | freq_table[i].driver_data = i; | ||
77 | freq_table[i].frequency = rate / 1000; | ||
78 | } | ||
79 | |||
80 | freq_table[i].driver_data = i; | ||
81 | freq_table[i].frequency = CPUFREQ_TABLE_END; | ||
82 | |||
83 | *table = &freq_table[0]; | ||
84 | |||
85 | out: | ||
86 | rcu_read_unlock(); | ||
87 | if (ret) | ||
88 | kfree(freq_table); | ||
89 | |||
90 | return ret; | ||
91 | } | ||
92 | EXPORT_SYMBOL_GPL(dev_pm_opp_init_cpufreq_table); | ||
93 | |||
94 | /** | ||
95 | * dev_pm_opp_free_cpufreq_table() - free the cpufreq table | ||
96 | * @dev: device for which we do this operation | ||
97 | * @table: table to free | ||
98 | * | ||
99 | * Free up the table allocated by dev_pm_opp_init_cpufreq_table | ||
100 | */ | ||
101 | void dev_pm_opp_free_cpufreq_table(struct device *dev, | ||
102 | struct cpufreq_frequency_table **table) | ||
103 | { | ||
104 | if (!table) | ||
105 | return; | ||
106 | |||
107 | kfree(*table); | ||
108 | *table = NULL; | ||
109 | } | ||
110 | EXPORT_SYMBOL_GPL(dev_pm_opp_free_cpufreq_table); | ||
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index ecaaebf969fc..0cd9b4dcef99 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c | |||
@@ -182,11 +182,11 @@ static void cpufreq_stats_free_table(unsigned int cpu) | |||
182 | 182 | ||
183 | static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) | 183 | static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) |
184 | { | 184 | { |
185 | unsigned int i, j, count = 0, ret = 0; | 185 | unsigned int i, count = 0, ret = 0; |
186 | struct cpufreq_stats *stat; | 186 | struct cpufreq_stats *stat; |
187 | unsigned int alloc_size; | 187 | unsigned int alloc_size; |
188 | unsigned int cpu = policy->cpu; | 188 | unsigned int cpu = policy->cpu; |
189 | struct cpufreq_frequency_table *table; | 189 | struct cpufreq_frequency_table *pos, *table; |
190 | 190 | ||
191 | table = cpufreq_frequency_get_table(cpu); | 191 | table = cpufreq_frequency_get_table(cpu); |
192 | if (unlikely(!table)) | 192 | if (unlikely(!table)) |
@@ -205,12 +205,8 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) | |||
205 | stat->cpu = cpu; | 205 | stat->cpu = cpu; |
206 | per_cpu(cpufreq_stats_table, cpu) = stat; | 206 | per_cpu(cpufreq_stats_table, cpu) = stat; |
207 | 207 | ||
208 | for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { | 208 | cpufreq_for_each_valid_entry(pos, table) |
209 | unsigned int freq = table[i].frequency; | ||
210 | if (freq == CPUFREQ_ENTRY_INVALID) | ||
211 | continue; | ||
212 | count++; | 209 | count++; |
213 | } | ||
214 | 210 | ||
215 | alloc_size = count * sizeof(int) + count * sizeof(u64); | 211 | alloc_size = count * sizeof(int) + count * sizeof(u64); |
216 | 212 | ||
@@ -228,15 +224,11 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) | |||
228 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS | 224 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS |
229 | stat->trans_table = stat->freq_table + count; | 225 | stat->trans_table = stat->freq_table + count; |
230 | #endif | 226 | #endif |
231 | j = 0; | 227 | i = 0; |
232 | for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { | 228 | cpufreq_for_each_valid_entry(pos, table) |
233 | unsigned int freq = table[i].frequency; | 229 | if (freq_table_get_index(stat, pos->frequency) == -1) |
234 | if (freq == CPUFREQ_ENTRY_INVALID) | 230 | stat->freq_table[i++] = pos->frequency; |
235 | continue; | 231 | stat->state_num = i; |
236 | if (freq_table_get_index(stat, freq) == -1) | ||
237 | stat->freq_table[j++] = freq; | ||
238 | } | ||
239 | stat->state_num = j; | ||
240 | spin_lock(&cpufreq_stats_lock); | 232 | spin_lock(&cpufreq_stats_lock); |
241 | stat->last_time = get_jiffies_64(); | 233 | stat->last_time = get_jiffies_64(); |
242 | stat->last_index = freq_table_get_index(stat, policy->cur); | 234 | stat->last_index = freq_table_get_index(stat, policy->cur); |
diff --git a/drivers/cpufreq/dbx500-cpufreq.c b/drivers/cpufreq/dbx500-cpufreq.c index 412a78bb0c94..4bebc1b5db48 100644 --- a/drivers/cpufreq/dbx500-cpufreq.c +++ b/drivers/cpufreq/dbx500-cpufreq.c | |||
@@ -45,7 +45,7 @@ static struct cpufreq_driver dbx500_cpufreq_driver = { | |||
45 | 45 | ||
46 | static int dbx500_cpufreq_probe(struct platform_device *pdev) | 46 | static int dbx500_cpufreq_probe(struct platform_device *pdev) |
47 | { | 47 | { |
48 | int i = 0; | 48 | struct cpufreq_frequency_table *pos; |
49 | 49 | ||
50 | freq_table = dev_get_platdata(&pdev->dev); | 50 | freq_table = dev_get_platdata(&pdev->dev); |
51 | if (!freq_table) { | 51 | if (!freq_table) { |
@@ -60,10 +60,8 @@ static int dbx500_cpufreq_probe(struct platform_device *pdev) | |||
60 | } | 60 | } |
61 | 61 | ||
62 | pr_info("dbx500-cpufreq: Available frequencies:\n"); | 62 | pr_info("dbx500-cpufreq: Available frequencies:\n"); |
63 | while (freq_table[i].frequency != CPUFREQ_TABLE_END) { | 63 | cpufreq_for_each_entry(pos, freq_table) |
64 | pr_info(" %d Mhz\n", freq_table[i].frequency/1000); | 64 | pr_info(" %d Mhz\n", pos->frequency / 1000); |
65 | i++; | ||
66 | } | ||
67 | 65 | ||
68 | return cpufreq_register_driver(&dbx500_cpufreq_driver); | 66 | return cpufreq_register_driver(&dbx500_cpufreq_driver); |
69 | } | 67 | } |
diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c index 7f5d2a68c353..1c06e786c9ba 100644 --- a/drivers/cpufreq/elanfreq.c +++ b/drivers/cpufreq/elanfreq.c | |||
@@ -147,7 +147,7 @@ static int elanfreq_target(struct cpufreq_policy *policy, | |||
147 | static int elanfreq_cpu_init(struct cpufreq_policy *policy) | 147 | static int elanfreq_cpu_init(struct cpufreq_policy *policy) |
148 | { | 148 | { |
149 | struct cpuinfo_x86 *c = &cpu_data(0); | 149 | struct cpuinfo_x86 *c = &cpu_data(0); |
150 | unsigned int i; | 150 | struct cpufreq_frequency_table *pos; |
151 | 151 | ||
152 | /* capability check */ | 152 | /* capability check */ |
153 | if ((c->x86_vendor != X86_VENDOR_AMD) || | 153 | if ((c->x86_vendor != X86_VENDOR_AMD) || |
@@ -159,10 +159,9 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy) | |||
159 | max_freq = elanfreq_get_cpu_frequency(0); | 159 | max_freq = elanfreq_get_cpu_frequency(0); |
160 | 160 | ||
161 | /* table init */ | 161 | /* table init */ |
162 | for (i = 0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) { | 162 | cpufreq_for_each_entry(pos, elanfreq_table) |
163 | if (elanfreq_table[i].frequency > max_freq) | 163 | if (pos->frequency > max_freq) |
164 | elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 164 | pos->frequency = CPUFREQ_ENTRY_INVALID; |
165 | } | ||
166 | 165 | ||
167 | /* cpuinfo and default policy values */ | 166 | /* cpuinfo and default policy values */ |
168 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 167 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index 348c8bafe436..1e0ec57bf6e3 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c | |||
@@ -28,17 +28,16 @@ static unsigned int locking_frequency; | |||
28 | static int exynos_cpufreq_get_index(unsigned int freq) | 28 | static int exynos_cpufreq_get_index(unsigned int freq) |
29 | { | 29 | { |
30 | struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; | 30 | struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; |
31 | int index; | 31 | struct cpufreq_frequency_table *pos; |
32 | 32 | ||
33 | for (index = 0; | 33 | cpufreq_for_each_entry(pos, freq_table) |
34 | freq_table[index].frequency != CPUFREQ_TABLE_END; index++) | 34 | if (pos->frequency == freq) |
35 | if (freq_table[index].frequency == freq) | ||
36 | break; | 35 | break; |
37 | 36 | ||
38 | if (freq_table[index].frequency == CPUFREQ_TABLE_END) | 37 | if (pos->frequency == CPUFREQ_TABLE_END) |
39 | return -EINVAL; | 38 | return -EINVAL; |
40 | 39 | ||
41 | return index; | 40 | return pos - freq_table; |
42 | } | 41 | } |
43 | 42 | ||
44 | static int exynos_cpufreq_scale(unsigned int target_freq) | 43 | static int exynos_cpufreq_scale(unsigned int target_freq) |
@@ -48,6 +47,7 @@ static int exynos_cpufreq_scale(unsigned int target_freq) | |||
48 | struct cpufreq_policy *policy = cpufreq_cpu_get(0); | 47 | struct cpufreq_policy *policy = cpufreq_cpu_get(0); |
49 | unsigned int arm_volt, safe_arm_volt = 0; | 48 | unsigned int arm_volt, safe_arm_volt = 0; |
50 | unsigned int mpll_freq_khz = exynos_info->mpll_freq_khz; | 49 | unsigned int mpll_freq_khz = exynos_info->mpll_freq_khz; |
50 | struct device *dev = exynos_info->dev; | ||
51 | unsigned int old_freq; | 51 | unsigned int old_freq; |
52 | int index, old_index; | 52 | int index, old_index; |
53 | int ret = 0; | 53 | int ret = 0; |
@@ -89,8 +89,8 @@ static int exynos_cpufreq_scale(unsigned int target_freq) | |||
89 | /* Firstly, voltage up to increase frequency */ | 89 | /* Firstly, voltage up to increase frequency */ |
90 | ret = regulator_set_voltage(arm_regulator, arm_volt, arm_volt); | 90 | ret = regulator_set_voltage(arm_regulator, arm_volt, arm_volt); |
91 | if (ret) { | 91 | if (ret) { |
92 | pr_err("%s: failed to set cpu voltage to %d\n", | 92 | dev_err(dev, "failed to set cpu voltage to %d\n", |
93 | __func__, arm_volt); | 93 | arm_volt); |
94 | return ret; | 94 | return ret; |
95 | } | 95 | } |
96 | } | 96 | } |
@@ -99,8 +99,8 @@ static int exynos_cpufreq_scale(unsigned int target_freq) | |||
99 | ret = regulator_set_voltage(arm_regulator, safe_arm_volt, | 99 | ret = regulator_set_voltage(arm_regulator, safe_arm_volt, |
100 | safe_arm_volt); | 100 | safe_arm_volt); |
101 | if (ret) { | 101 | if (ret) { |
102 | pr_err("%s: failed to set cpu voltage to %d\n", | 102 | dev_err(dev, "failed to set cpu voltage to %d\n", |
103 | __func__, safe_arm_volt); | 103 | safe_arm_volt); |
104 | return ret; | 104 | return ret; |
105 | } | 105 | } |
106 | } | 106 | } |
@@ -114,8 +114,8 @@ static int exynos_cpufreq_scale(unsigned int target_freq) | |||
114 | ret = regulator_set_voltage(arm_regulator, arm_volt, | 114 | ret = regulator_set_voltage(arm_regulator, arm_volt, |
115 | arm_volt); | 115 | arm_volt); |
116 | if (ret) { | 116 | if (ret) { |
117 | pr_err("%s: failed to set cpu voltage to %d\n", | 117 | dev_err(dev, "failed to set cpu voltage to %d\n", |
118 | __func__, arm_volt); | 118 | arm_volt); |
119 | goto out; | 119 | goto out; |
120 | } | 120 | } |
121 | } | 121 | } |
@@ -162,6 +162,8 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
162 | if (!exynos_info) | 162 | if (!exynos_info) |
163 | return -ENOMEM; | 163 | return -ENOMEM; |
164 | 164 | ||
165 | exynos_info->dev = &pdev->dev; | ||
166 | |||
165 | if (of_machine_is_compatible("samsung,exynos4210")) { | 167 | if (of_machine_is_compatible("samsung,exynos4210")) { |
166 | exynos_info->type = EXYNOS_SOC_4210; | 168 | exynos_info->type = EXYNOS_SOC_4210; |
167 | ret = exynos4210_cpufreq_init(exynos_info); | 169 | ret = exynos4210_cpufreq_init(exynos_info); |
@@ -183,13 +185,13 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
183 | goto err_vdd_arm; | 185 | goto err_vdd_arm; |
184 | 186 | ||
185 | if (exynos_info->set_freq == NULL) { | 187 | if (exynos_info->set_freq == NULL) { |
186 | pr_err("%s: No set_freq function (ERR)\n", __func__); | 188 | dev_err(&pdev->dev, "No set_freq function (ERR)\n"); |
187 | goto err_vdd_arm; | 189 | goto err_vdd_arm; |
188 | } | 190 | } |
189 | 191 | ||
190 | arm_regulator = regulator_get(NULL, "vdd_arm"); | 192 | arm_regulator = regulator_get(NULL, "vdd_arm"); |
191 | if (IS_ERR(arm_regulator)) { | 193 | if (IS_ERR(arm_regulator)) { |
192 | pr_err("%s: failed to get resource vdd_arm\n", __func__); | 194 | dev_err(&pdev->dev, "failed to get resource vdd_arm\n"); |
193 | goto err_vdd_arm; | 195 | goto err_vdd_arm; |
194 | } | 196 | } |
195 | 197 | ||
@@ -199,7 +201,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
199 | if (!cpufreq_register_driver(&exynos_driver)) | 201 | if (!cpufreq_register_driver(&exynos_driver)) |
200 | return 0; | 202 | return 0; |
201 | 203 | ||
202 | pr_err("%s: failed to register cpufreq driver\n", __func__); | 204 | dev_err(&pdev->dev, "failed to register cpufreq driver\n"); |
203 | regulator_put(arm_regulator); | 205 | regulator_put(arm_regulator); |
204 | err_vdd_arm: | 206 | err_vdd_arm: |
205 | kfree(exynos_info); | 207 | kfree(exynos_info); |
diff --git a/drivers/cpufreq/exynos-cpufreq.h b/drivers/cpufreq/exynos-cpufreq.h index 51af42e1b7fe..9f2062a7cc02 100644 --- a/drivers/cpufreq/exynos-cpufreq.h +++ b/drivers/cpufreq/exynos-cpufreq.h | |||
@@ -42,6 +42,7 @@ struct apll_freq { | |||
42 | 42 | ||
43 | struct exynos_dvfs_info { | 43 | struct exynos_dvfs_info { |
44 | enum exynos_soc_type type; | 44 | enum exynos_soc_type type; |
45 | struct device *dev; | ||
45 | unsigned long mpll_freq_khz; | 46 | unsigned long mpll_freq_khz; |
46 | unsigned int pll_safe_idx; | 47 | unsigned int pll_safe_idx; |
47 | struct clk *cpu_clk; | 48 | struct clk *cpu_clk; |
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index a6b8214d7b77..f33f25b483ca 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c | |||
@@ -114,25 +114,23 @@ static struct cpufreq_freqs freqs; | |||
114 | 114 | ||
115 | static int init_div_table(void) | 115 | static int init_div_table(void) |
116 | { | 116 | { |
117 | struct cpufreq_frequency_table *freq_tbl = dvfs_info->freq_table; | 117 | struct cpufreq_frequency_table *pos, *freq_tbl = dvfs_info->freq_table; |
118 | unsigned int tmp, clk_div, ema_div, freq, volt_id; | 118 | unsigned int tmp, clk_div, ema_div, freq, volt_id; |
119 | int i = 0; | ||
120 | struct dev_pm_opp *opp; | 119 | struct dev_pm_opp *opp; |
121 | 120 | ||
122 | rcu_read_lock(); | 121 | rcu_read_lock(); |
123 | for (i = 0; freq_tbl[i].frequency != CPUFREQ_TABLE_END; i++) { | 122 | cpufreq_for_each_entry(pos, freq_tbl) { |
124 | |||
125 | opp = dev_pm_opp_find_freq_exact(dvfs_info->dev, | 123 | opp = dev_pm_opp_find_freq_exact(dvfs_info->dev, |
126 | freq_tbl[i].frequency * 1000, true); | 124 | pos->frequency * 1000, true); |
127 | if (IS_ERR(opp)) { | 125 | if (IS_ERR(opp)) { |
128 | rcu_read_unlock(); | 126 | rcu_read_unlock(); |
129 | dev_err(dvfs_info->dev, | 127 | dev_err(dvfs_info->dev, |
130 | "failed to find valid OPP for %u KHZ\n", | 128 | "failed to find valid OPP for %u KHZ\n", |
131 | freq_tbl[i].frequency); | 129 | pos->frequency); |
132 | return PTR_ERR(opp); | 130 | return PTR_ERR(opp); |
133 | } | 131 | } |
134 | 132 | ||
135 | freq = freq_tbl[i].frequency / 1000; /* In MHZ */ | 133 | freq = pos->frequency / 1000; /* In MHZ */ |
136 | clk_div = ((freq / CPU_DIV_FREQ_MAX) & P0_7_CPUCLKDEV_MASK) | 134 | clk_div = ((freq / CPU_DIV_FREQ_MAX) & P0_7_CPUCLKDEV_MASK) |
137 | << P0_7_CPUCLKDEV_SHIFT; | 135 | << P0_7_CPUCLKDEV_SHIFT; |
138 | clk_div |= ((freq / CPU_ATB_FREQ_MAX) & P0_7_ATBCLKDEV_MASK) | 136 | clk_div |= ((freq / CPU_ATB_FREQ_MAX) & P0_7_ATBCLKDEV_MASK) |
@@ -157,7 +155,8 @@ static int init_div_table(void) | |||
157 | tmp = (clk_div | ema_div | (volt_id << P0_7_VDD_SHIFT) | 155 | tmp = (clk_div | ema_div | (volt_id << P0_7_VDD_SHIFT) |
158 | | ((freq / FREQ_UNIT) << P0_7_FREQ_SHIFT)); | 156 | | ((freq / FREQ_UNIT) << P0_7_FREQ_SHIFT)); |
159 | 157 | ||
160 | __raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 * i); | 158 | __raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 * |
159 | (pos - freq_tbl)); | ||
161 | } | 160 | } |
162 | 161 | ||
163 | rcu_read_unlock(); | 162 | rcu_read_unlock(); |
@@ -166,8 +165,9 @@ static int init_div_table(void) | |||
166 | 165 | ||
167 | static void exynos_enable_dvfs(unsigned int cur_frequency) | 166 | static void exynos_enable_dvfs(unsigned int cur_frequency) |
168 | { | 167 | { |
169 | unsigned int tmp, i, cpu; | 168 | unsigned int tmp, cpu; |
170 | struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; | 169 | struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; |
170 | struct cpufreq_frequency_table *pos; | ||
171 | /* Disable DVFS */ | 171 | /* Disable DVFS */ |
172 | __raw_writel(0, dvfs_info->base + XMU_DVFS_CTRL); | 172 | __raw_writel(0, dvfs_info->base + XMU_DVFS_CTRL); |
173 | 173 | ||
@@ -182,15 +182,15 @@ static void exynos_enable_dvfs(unsigned int cur_frequency) | |||
182 | __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQEN); | 182 | __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQEN); |
183 | 183 | ||
184 | /* Set initial performance index */ | 184 | /* Set initial performance index */ |
185 | for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) | 185 | cpufreq_for_each_entry(pos, freq_table) |
186 | if (freq_table[i].frequency == cur_frequency) | 186 | if (pos->frequency == cur_frequency) |
187 | break; | 187 | break; |
188 | 188 | ||
189 | if (freq_table[i].frequency == CPUFREQ_TABLE_END) { | 189 | if (pos->frequency == CPUFREQ_TABLE_END) { |
190 | dev_crit(dvfs_info->dev, "Boot up frequency not supported\n"); | 190 | dev_crit(dvfs_info->dev, "Boot up frequency not supported\n"); |
191 | /* Assign the highest frequency */ | 191 | /* Assign the highest frequency */ |
192 | i = 0; | 192 | pos = freq_table; |
193 | cur_frequency = freq_table[i].frequency; | 193 | cur_frequency = pos->frequency; |
194 | } | 194 | } |
195 | 195 | ||
196 | dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ", | 196 | dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ", |
@@ -199,7 +199,7 @@ static void exynos_enable_dvfs(unsigned int cur_frequency) | |||
199 | for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) { | 199 | for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) { |
200 | tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); | 200 | tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); |
201 | tmp &= ~(P_VALUE_MASK << C0_3_PSTATE_NEW_SHIFT); | 201 | tmp &= ~(P_VALUE_MASK << C0_3_PSTATE_NEW_SHIFT); |
202 | tmp |= (i << C0_3_PSTATE_NEW_SHIFT); | 202 | tmp |= ((pos - freq_table) << C0_3_PSTATE_NEW_SHIFT); |
203 | __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); | 203 | __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); |
204 | } | 204 | } |
205 | 205 | ||
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 08e7bbcf6d73..1632981c4b25 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c | |||
@@ -21,22 +21,19 @@ | |||
21 | int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, | 21 | int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, |
22 | struct cpufreq_frequency_table *table) | 22 | struct cpufreq_frequency_table *table) |
23 | { | 23 | { |
24 | struct cpufreq_frequency_table *pos; | ||
24 | unsigned int min_freq = ~0; | 25 | unsigned int min_freq = ~0; |
25 | unsigned int max_freq = 0; | 26 | unsigned int max_freq = 0; |
26 | unsigned int i; | 27 | unsigned int freq; |
27 | 28 | ||
28 | for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { | 29 | cpufreq_for_each_valid_entry(pos, table) { |
29 | unsigned int freq = table[i].frequency; | 30 | freq = pos->frequency; |
30 | if (freq == CPUFREQ_ENTRY_INVALID) { | ||
31 | pr_debug("table entry %u is invalid, skipping\n", i); | ||
32 | 31 | ||
33 | continue; | ||
34 | } | ||
35 | if (!cpufreq_boost_enabled() | 32 | if (!cpufreq_boost_enabled() |
36 | && (table[i].flags & CPUFREQ_BOOST_FREQ)) | 33 | && (pos->flags & CPUFREQ_BOOST_FREQ)) |
37 | continue; | 34 | continue; |
38 | 35 | ||
39 | pr_debug("table entry %u: %u kHz\n", i, freq); | 36 | pr_debug("table entry %u: %u kHz\n", (int)(pos - table), freq); |
40 | if (freq < min_freq) | 37 | if (freq < min_freq) |
41 | min_freq = freq; | 38 | min_freq = freq; |
42 | if (freq > max_freq) | 39 | if (freq > max_freq) |
@@ -57,7 +54,8 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_cpuinfo); | |||
57 | int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, | 54 | int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, |
58 | struct cpufreq_frequency_table *table) | 55 | struct cpufreq_frequency_table *table) |
59 | { | 56 | { |
60 | unsigned int next_larger = ~0, freq, i = 0; | 57 | struct cpufreq_frequency_table *pos; |
58 | unsigned int freq, next_larger = ~0; | ||
61 | bool found = false; | 59 | bool found = false; |
62 | 60 | ||
63 | pr_debug("request for verification of policy (%u - %u kHz) for cpu %u\n", | 61 | pr_debug("request for verification of policy (%u - %u kHz) for cpu %u\n", |
@@ -65,9 +63,9 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, | |||
65 | 63 | ||
66 | cpufreq_verify_within_cpu_limits(policy); | 64 | cpufreq_verify_within_cpu_limits(policy); |
67 | 65 | ||
68 | for (; freq = table[i].frequency, freq != CPUFREQ_TABLE_END; i++) { | 66 | cpufreq_for_each_valid_entry(pos, table) { |
69 | if (freq == CPUFREQ_ENTRY_INVALID) | 67 | freq = pos->frequency; |
70 | continue; | 68 | |
71 | if ((freq >= policy->min) && (freq <= policy->max)) { | 69 | if ((freq >= policy->min) && (freq <= policy->max)) { |
72 | found = true; | 70 | found = true; |
73 | break; | 71 | break; |
@@ -118,7 +116,8 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, | |||
118 | .driver_data = ~0, | 116 | .driver_data = ~0, |
119 | .frequency = 0, | 117 | .frequency = 0, |
120 | }; | 118 | }; |
121 | unsigned int i; | 119 | struct cpufreq_frequency_table *pos; |
120 | unsigned int freq, i = 0; | ||
122 | 121 | ||
123 | pr_debug("request for target %u kHz (relation: %u) for cpu %u\n", | 122 | pr_debug("request for target %u kHz (relation: %u) for cpu %u\n", |
124 | target_freq, relation, policy->cpu); | 123 | target_freq, relation, policy->cpu); |
@@ -132,15 +131,19 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, | |||
132 | break; | 131 | break; |
133 | } | 132 | } |
134 | 133 | ||
135 | for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { | 134 | cpufreq_for_each_valid_entry(pos, table) { |
136 | unsigned int freq = table[i].frequency; | 135 | freq = pos->frequency; |
137 | if (freq == CPUFREQ_ENTRY_INVALID) | 136 | |
138 | continue; | 137 | i = pos - table; |
139 | if ((freq < policy->min) || (freq > policy->max)) | 138 | if ((freq < policy->min) || (freq > policy->max)) |
140 | continue; | 139 | continue; |
140 | if (freq == target_freq) { | ||
141 | optimal.driver_data = i; | ||
142 | break; | ||
143 | } | ||
141 | switch (relation) { | 144 | switch (relation) { |
142 | case CPUFREQ_RELATION_H: | 145 | case CPUFREQ_RELATION_H: |
143 | if (freq <= target_freq) { | 146 | if (freq < target_freq) { |
144 | if (freq >= optimal.frequency) { | 147 | if (freq >= optimal.frequency) { |
145 | optimal.frequency = freq; | 148 | optimal.frequency = freq; |
146 | optimal.driver_data = i; | 149 | optimal.driver_data = i; |
@@ -153,7 +156,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, | |||
153 | } | 156 | } |
154 | break; | 157 | break; |
155 | case CPUFREQ_RELATION_L: | 158 | case CPUFREQ_RELATION_L: |
156 | if (freq >= target_freq) { | 159 | if (freq > target_freq) { |
157 | if (freq <= optimal.frequency) { | 160 | if (freq <= optimal.frequency) { |
158 | optimal.frequency = freq; | 161 | optimal.frequency = freq; |
159 | optimal.driver_data = i; | 162 | optimal.driver_data = i; |
@@ -184,8 +187,7 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target); | |||
184 | int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, | 187 | int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, |
185 | unsigned int freq) | 188 | unsigned int freq) |
186 | { | 189 | { |
187 | struct cpufreq_frequency_table *table; | 190 | struct cpufreq_frequency_table *pos, *table; |
188 | int i; | ||
189 | 191 | ||
190 | table = cpufreq_frequency_get_table(policy->cpu); | 192 | table = cpufreq_frequency_get_table(policy->cpu); |
191 | if (unlikely(!table)) { | 193 | if (unlikely(!table)) { |
@@ -193,10 +195,9 @@ int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, | |||
193 | return -ENOENT; | 195 | return -ENOENT; |
194 | } | 196 | } |
195 | 197 | ||
196 | for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { | 198 | cpufreq_for_each_valid_entry(pos, table) |
197 | if (table[i].frequency == freq) | 199 | if (pos->frequency == freq) |
198 | return i; | 200 | return pos - table; |
199 | } | ||
200 | 201 | ||
201 | return -EINVAL; | 202 | return -EINVAL; |
202 | } | 203 | } |
@@ -208,16 +209,13 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_index); | |||
208 | static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf, | 209 | static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf, |
209 | bool show_boost) | 210 | bool show_boost) |
210 | { | 211 | { |
211 | unsigned int i = 0; | ||
212 | ssize_t count = 0; | 212 | ssize_t count = 0; |
213 | struct cpufreq_frequency_table *table = policy->freq_table; | 213 | struct cpufreq_frequency_table *pos, *table = policy->freq_table; |
214 | 214 | ||
215 | if (!table) | 215 | if (!table) |
216 | return -ENODEV; | 216 | return -ENODEV; |
217 | 217 | ||
218 | for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { | 218 | cpufreq_for_each_valid_entry(pos, table) { |
219 | if (table[i].frequency == CPUFREQ_ENTRY_INVALID) | ||
220 | continue; | ||
221 | /* | 219 | /* |
222 | * show_boost = true and driver_data = BOOST freq | 220 | * show_boost = true and driver_data = BOOST freq |
223 | * display BOOST freqs | 221 | * display BOOST freqs |
@@ -229,10 +227,10 @@ static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf, | |||
229 | * show_boost = false and driver_data != BOOST freq | 227 | * show_boost = false and driver_data != BOOST freq |
230 | * display NON BOOST freqs | 228 | * display NON BOOST freqs |
231 | */ | 229 | */ |
232 | if (show_boost ^ (table[i].flags & CPUFREQ_BOOST_FREQ)) | 230 | if (show_boost ^ (pos->flags & CPUFREQ_BOOST_FREQ)) |
233 | continue; | 231 | continue; |
234 | 232 | ||
235 | count += sprintf(&buf[count], "%d ", table[i].frequency); | 233 | count += sprintf(&buf[count], "%d ", pos->frequency); |
236 | } | 234 | } |
237 | count += sprintf(&buf[count], "\n"); | 235 | count += sprintf(&buf[count], "\n"); |
238 | 236 | ||
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index e27fca86fe4f..af366c21d4b4 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/clk.h> | 9 | #include <linux/clk.h> |
10 | #include <linux/cpu.h> | 10 | #include <linux/cpu.h> |
11 | #include <linux/cpufreq.h> | 11 | #include <linux/cpufreq.h> |
12 | #include <linux/delay.h> | ||
13 | #include <linux/err.h> | 12 | #include <linux/err.h> |
14 | #include <linux/module.h> | 13 | #include <linux/module.h> |
15 | #include <linux/of.h> | 14 | #include <linux/of.h> |
@@ -170,25 +169,25 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) | |||
170 | return -ENOENT; | 169 | return -ENOENT; |
171 | } | 170 | } |
172 | 171 | ||
173 | arm_clk = devm_clk_get(cpu_dev, "arm"); | 172 | arm_clk = clk_get(cpu_dev, "arm"); |
174 | pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys"); | 173 | pll1_sys_clk = clk_get(cpu_dev, "pll1_sys"); |
175 | pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw"); | 174 | pll1_sw_clk = clk_get(cpu_dev, "pll1_sw"); |
176 | step_clk = devm_clk_get(cpu_dev, "step"); | 175 | step_clk = clk_get(cpu_dev, "step"); |
177 | pll2_pfd2_396m_clk = devm_clk_get(cpu_dev, "pll2_pfd2_396m"); | 176 | pll2_pfd2_396m_clk = clk_get(cpu_dev, "pll2_pfd2_396m"); |
178 | if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) || | 177 | if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) || |
179 | IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) { | 178 | IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) { |
180 | dev_err(cpu_dev, "failed to get clocks\n"); | 179 | dev_err(cpu_dev, "failed to get clocks\n"); |
181 | ret = -ENOENT; | 180 | ret = -ENOENT; |
182 | goto put_node; | 181 | goto put_clk; |
183 | } | 182 | } |
184 | 183 | ||
185 | arm_reg = devm_regulator_get(cpu_dev, "arm"); | 184 | arm_reg = regulator_get(cpu_dev, "arm"); |
186 | pu_reg = devm_regulator_get(cpu_dev, "pu"); | 185 | pu_reg = regulator_get(cpu_dev, "pu"); |
187 | soc_reg = devm_regulator_get(cpu_dev, "soc"); | 186 | soc_reg = regulator_get(cpu_dev, "soc"); |
188 | if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) { | 187 | if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) { |
189 | dev_err(cpu_dev, "failed to get regulators\n"); | 188 | dev_err(cpu_dev, "failed to get regulators\n"); |
190 | ret = -ENOENT; | 189 | ret = -ENOENT; |
191 | goto put_node; | 190 | goto put_reg; |
192 | } | 191 | } |
193 | 192 | ||
194 | /* | 193 | /* |
@@ -201,21 +200,21 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) | |||
201 | ret = of_init_opp_table(cpu_dev); | 200 | ret = of_init_opp_table(cpu_dev); |
202 | if (ret < 0) { | 201 | if (ret < 0) { |
203 | dev_err(cpu_dev, "failed to init OPP table: %d\n", ret); | 202 | dev_err(cpu_dev, "failed to init OPP table: %d\n", ret); |
204 | goto put_node; | 203 | goto put_reg; |
205 | } | 204 | } |
206 | 205 | ||
207 | num = dev_pm_opp_get_opp_count(cpu_dev); | 206 | num = dev_pm_opp_get_opp_count(cpu_dev); |
208 | if (num < 0) { | 207 | if (num < 0) { |
209 | ret = num; | 208 | ret = num; |
210 | dev_err(cpu_dev, "no OPP table is found: %d\n", ret); | 209 | dev_err(cpu_dev, "no OPP table is found: %d\n", ret); |
211 | goto put_node; | 210 | goto put_reg; |
212 | } | 211 | } |
213 | } | 212 | } |
214 | 213 | ||
215 | ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); | 214 | ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); |
216 | if (ret) { | 215 | if (ret) { |
217 | dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); | 216 | dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); |
218 | goto put_node; | 217 | goto put_reg; |
219 | } | 218 | } |
220 | 219 | ||
221 | /* Make imx6_soc_volt array's size same as arm opp number */ | 220 | /* Make imx6_soc_volt array's size same as arm opp number */ |
@@ -301,7 +300,24 @@ soc_opp_out: | |||
301 | 300 | ||
302 | free_freq_table: | 301 | free_freq_table: |
303 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); | 302 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); |
304 | put_node: | 303 | put_reg: |
304 | if (!IS_ERR(arm_reg)) | ||
305 | regulator_put(arm_reg); | ||
306 | if (!IS_ERR(pu_reg)) | ||
307 | regulator_put(pu_reg); | ||
308 | if (!IS_ERR(soc_reg)) | ||
309 | regulator_put(soc_reg); | ||
310 | put_clk: | ||
311 | if (!IS_ERR(arm_clk)) | ||
312 | clk_put(arm_clk); | ||
313 | if (!IS_ERR(pll1_sys_clk)) | ||
314 | clk_put(pll1_sys_clk); | ||
315 | if (!IS_ERR(pll1_sw_clk)) | ||
316 | clk_put(pll1_sw_clk); | ||
317 | if (!IS_ERR(step_clk)) | ||
318 | clk_put(step_clk); | ||
319 | if (!IS_ERR(pll2_pfd2_396m_clk)) | ||
320 | clk_put(pll2_pfd2_396m_clk); | ||
305 | of_node_put(np); | 321 | of_node_put(np); |
306 | return ret; | 322 | return ret; |
307 | } | 323 | } |
@@ -310,6 +326,14 @@ static int imx6q_cpufreq_remove(struct platform_device *pdev) | |||
310 | { | 326 | { |
311 | cpufreq_unregister_driver(&imx6q_cpufreq_driver); | 327 | cpufreq_unregister_driver(&imx6q_cpufreq_driver); |
312 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); | 328 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); |
329 | regulator_put(arm_reg); | ||
330 | regulator_put(pu_reg); | ||
331 | regulator_put(soc_reg); | ||
332 | clk_put(arm_clk); | ||
333 | clk_put(pll1_sys_clk); | ||
334 | clk_put(pll1_sw_clk); | ||
335 | clk_put(step_clk); | ||
336 | clk_put(pll2_pfd2_396m_clk); | ||
313 | 337 | ||
314 | return 0; | 338 | return 0; |
315 | } | 339 | } |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index eab8ccfe6beb..aebd4572eb6d 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -32,18 +32,16 @@ | |||
32 | #include <asm/msr.h> | 32 | #include <asm/msr.h> |
33 | #include <asm/cpu_device_id.h> | 33 | #include <asm/cpu_device_id.h> |
34 | 34 | ||
35 | #define SAMPLE_COUNT 3 | ||
36 | |||
37 | #define BYT_RATIOS 0x66a | 35 | #define BYT_RATIOS 0x66a |
38 | #define BYT_VIDS 0x66b | 36 | #define BYT_VIDS 0x66b |
39 | #define BYT_TURBO_RATIOS 0x66c | 37 | #define BYT_TURBO_RATIOS 0x66c |
40 | #define BYT_TURBO_VIDS 0x66d | 38 | #define BYT_TURBO_VIDS 0x66d |
41 | 39 | ||
42 | 40 | ||
43 | #define FRAC_BITS 6 | 41 | #define FRAC_BITS 8 |
44 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) | 42 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) |
45 | #define fp_toint(X) ((X) >> FRAC_BITS) | 43 | #define fp_toint(X) ((X) >> FRAC_BITS) |
46 | #define FP_ROUNDUP(X) ((X) += 1 << FRAC_BITS) | 44 | |
47 | 45 | ||
48 | static inline int32_t mul_fp(int32_t x, int32_t y) | 46 | static inline int32_t mul_fp(int32_t x, int32_t y) |
49 | { | 47 | { |
@@ -59,8 +57,8 @@ struct sample { | |||
59 | int32_t core_pct_busy; | 57 | int32_t core_pct_busy; |
60 | u64 aperf; | 58 | u64 aperf; |
61 | u64 mperf; | 59 | u64 mperf; |
62 | unsigned long long tsc; | ||
63 | int freq; | 60 | int freq; |
61 | ktime_t time; | ||
64 | }; | 62 | }; |
65 | 63 | ||
66 | struct pstate_data { | 64 | struct pstate_data { |
@@ -90,17 +88,15 @@ struct _pid { | |||
90 | struct cpudata { | 88 | struct cpudata { |
91 | int cpu; | 89 | int cpu; |
92 | 90 | ||
93 | char name[64]; | ||
94 | |||
95 | struct timer_list timer; | 91 | struct timer_list timer; |
96 | 92 | ||
97 | struct pstate_data pstate; | 93 | struct pstate_data pstate; |
98 | struct vid_data vid; | 94 | struct vid_data vid; |
99 | struct _pid pid; | 95 | struct _pid pid; |
100 | 96 | ||
97 | ktime_t last_sample_time; | ||
101 | u64 prev_aperf; | 98 | u64 prev_aperf; |
102 | u64 prev_mperf; | 99 | u64 prev_mperf; |
103 | unsigned long long prev_tsc; | ||
104 | struct sample sample; | 100 | struct sample sample; |
105 | }; | 101 | }; |
106 | 102 | ||
@@ -200,7 +196,10 @@ static signed int pid_calc(struct _pid *pid, int32_t busy) | |||
200 | pid->last_err = fp_error; | 196 | pid->last_err = fp_error; |
201 | 197 | ||
202 | result = pterm + mul_fp(pid->integral, pid->i_gain) + dterm; | 198 | result = pterm + mul_fp(pid->integral, pid->i_gain) + dterm; |
203 | 199 | if (result >= 0) | |
200 | result = result + (1 << (FRAC_BITS-1)); | ||
201 | else | ||
202 | result = result - (1 << (FRAC_BITS-1)); | ||
204 | return (signed int)fp_toint(result); | 203 | return (signed int)fp_toint(result); |
205 | } | 204 | } |
206 | 205 | ||
@@ -546,8 +545,6 @@ static inline void intel_pstate_pstate_decrease(struct cpudata *cpu, int steps) | |||
546 | 545 | ||
547 | static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) | 546 | static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) |
548 | { | 547 | { |
549 | sprintf(cpu->name, "Intel 2nd generation core"); | ||
550 | |||
551 | cpu->pstate.min_pstate = pstate_funcs.get_min(); | 548 | cpu->pstate.min_pstate = pstate_funcs.get_min(); |
552 | cpu->pstate.max_pstate = pstate_funcs.get_max(); | 549 | cpu->pstate.max_pstate = pstate_funcs.get_max(); |
553 | cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(); | 550 | cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(); |
@@ -557,50 +554,45 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) | |||
557 | intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate); | 554 | intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate); |
558 | } | 555 | } |
559 | 556 | ||
560 | static inline void intel_pstate_calc_busy(struct cpudata *cpu, | 557 | static inline void intel_pstate_calc_busy(struct cpudata *cpu) |
561 | struct sample *sample) | ||
562 | { | 558 | { |
563 | int32_t core_pct; | 559 | struct sample *sample = &cpu->sample; |
564 | int32_t c0_pct; | 560 | int64_t core_pct; |
561 | int32_t rem; | ||
565 | 562 | ||
566 | core_pct = div_fp(int_tofp((sample->aperf)), | 563 | core_pct = int_tofp(sample->aperf) * int_tofp(100); |
567 | int_tofp((sample->mperf))); | 564 | core_pct = div_u64_rem(core_pct, int_tofp(sample->mperf), &rem); |
568 | core_pct = mul_fp(core_pct, int_tofp(100)); | ||
569 | FP_ROUNDUP(core_pct); | ||
570 | 565 | ||
571 | c0_pct = div_fp(int_tofp(sample->mperf), int_tofp(sample->tsc)); | 566 | if ((rem << 1) >= int_tofp(sample->mperf)) |
567 | core_pct += 1; | ||
572 | 568 | ||
573 | sample->freq = fp_toint( | 569 | sample->freq = fp_toint( |
574 | mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct)); | 570 | mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct)); |
575 | 571 | ||
576 | sample->core_pct_busy = mul_fp(core_pct, c0_pct); | 572 | sample->core_pct_busy = (int32_t)core_pct; |
577 | } | 573 | } |
578 | 574 | ||
579 | static inline void intel_pstate_sample(struct cpudata *cpu) | 575 | static inline void intel_pstate_sample(struct cpudata *cpu) |
580 | { | 576 | { |
581 | u64 aperf, mperf; | 577 | u64 aperf, mperf; |
582 | unsigned long long tsc; | ||
583 | 578 | ||
584 | rdmsrl(MSR_IA32_APERF, aperf); | 579 | rdmsrl(MSR_IA32_APERF, aperf); |
585 | rdmsrl(MSR_IA32_MPERF, mperf); | 580 | rdmsrl(MSR_IA32_MPERF, mperf); |
586 | tsc = native_read_tsc(); | ||
587 | 581 | ||
588 | aperf = aperf >> FRAC_BITS; | 582 | aperf = aperf >> FRAC_BITS; |
589 | mperf = mperf >> FRAC_BITS; | 583 | mperf = mperf >> FRAC_BITS; |
590 | tsc = tsc >> FRAC_BITS; | ||
591 | 584 | ||
585 | cpu->last_sample_time = cpu->sample.time; | ||
586 | cpu->sample.time = ktime_get(); | ||
592 | cpu->sample.aperf = aperf; | 587 | cpu->sample.aperf = aperf; |
593 | cpu->sample.mperf = mperf; | 588 | cpu->sample.mperf = mperf; |
594 | cpu->sample.tsc = tsc; | ||
595 | cpu->sample.aperf -= cpu->prev_aperf; | 589 | cpu->sample.aperf -= cpu->prev_aperf; |
596 | cpu->sample.mperf -= cpu->prev_mperf; | 590 | cpu->sample.mperf -= cpu->prev_mperf; |
597 | cpu->sample.tsc -= cpu->prev_tsc; | ||
598 | 591 | ||
599 | intel_pstate_calc_busy(cpu, &cpu->sample); | 592 | intel_pstate_calc_busy(cpu); |
600 | 593 | ||
601 | cpu->prev_aperf = aperf; | 594 | cpu->prev_aperf = aperf; |
602 | cpu->prev_mperf = mperf; | 595 | cpu->prev_mperf = mperf; |
603 | cpu->prev_tsc = tsc; | ||
604 | } | 596 | } |
605 | 597 | ||
606 | static inline void intel_pstate_set_sample_time(struct cpudata *cpu) | 598 | static inline void intel_pstate_set_sample_time(struct cpudata *cpu) |
@@ -614,13 +606,25 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu) | |||
614 | 606 | ||
615 | static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu) | 607 | static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu) |
616 | { | 608 | { |
617 | int32_t core_busy, max_pstate, current_pstate; | 609 | int32_t core_busy, max_pstate, current_pstate, sample_ratio; |
610 | u32 duration_us; | ||
611 | u32 sample_time; | ||
618 | 612 | ||
619 | core_busy = cpu->sample.core_pct_busy; | 613 | core_busy = cpu->sample.core_pct_busy; |
620 | max_pstate = int_tofp(cpu->pstate.max_pstate); | 614 | max_pstate = int_tofp(cpu->pstate.max_pstate); |
621 | current_pstate = int_tofp(cpu->pstate.current_pstate); | 615 | current_pstate = int_tofp(cpu->pstate.current_pstate); |
622 | core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate)); | 616 | core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate)); |
623 | return FP_ROUNDUP(core_busy); | 617 | |
618 | sample_time = (pid_params.sample_rate_ms * USEC_PER_MSEC); | ||
619 | duration_us = (u32) ktime_us_delta(cpu->sample.time, | ||
620 | cpu->last_sample_time); | ||
621 | if (duration_us > sample_time * 3) { | ||
622 | sample_ratio = div_fp(int_tofp(sample_time), | ||
623 | int_tofp(duration_us)); | ||
624 | core_busy = mul_fp(core_busy, sample_ratio); | ||
625 | } | ||
626 | |||
627 | return core_busy; | ||
624 | } | 628 | } |
625 | 629 | ||
626 | static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) | 630 | static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) |
@@ -674,10 +678,13 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { | |||
674 | ICPU(0x37, byt_params), | 678 | ICPU(0x37, byt_params), |
675 | ICPU(0x3a, core_params), | 679 | ICPU(0x3a, core_params), |
676 | ICPU(0x3c, core_params), | 680 | ICPU(0x3c, core_params), |
681 | ICPU(0x3d, core_params), | ||
677 | ICPU(0x3e, core_params), | 682 | ICPU(0x3e, core_params), |
678 | ICPU(0x3f, core_params), | 683 | ICPU(0x3f, core_params), |
679 | ICPU(0x45, core_params), | 684 | ICPU(0x45, core_params), |
680 | ICPU(0x46, core_params), | 685 | ICPU(0x46, core_params), |
686 | ICPU(0x4f, core_params), | ||
687 | ICPU(0x56, core_params), | ||
681 | {} | 688 | {} |
682 | }; | 689 | }; |
683 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); | 690 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); |
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index 5c4369b5d834..c913906a719e 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c | |||
@@ -530,6 +530,7 @@ static int longhaul_get_ranges(void) | |||
530 | 530 | ||
531 | static void longhaul_setup_voltagescaling(void) | 531 | static void longhaul_setup_voltagescaling(void) |
532 | { | 532 | { |
533 | struct cpufreq_frequency_table *freq_pos; | ||
533 | union msr_longhaul longhaul; | 534 | union msr_longhaul longhaul; |
534 | struct mV_pos minvid, maxvid, vid; | 535 | struct mV_pos minvid, maxvid, vid; |
535 | unsigned int j, speed, pos, kHz_step, numvscales; | 536 | unsigned int j, speed, pos, kHz_step, numvscales; |
@@ -608,18 +609,16 @@ static void longhaul_setup_voltagescaling(void) | |||
608 | /* Calculate kHz for one voltage step */ | 609 | /* Calculate kHz for one voltage step */ |
609 | kHz_step = (highest_speed - min_vid_speed) / numvscales; | 610 | kHz_step = (highest_speed - min_vid_speed) / numvscales; |
610 | 611 | ||
611 | j = 0; | 612 | cpufreq_for_each_entry(freq_pos, longhaul_table) { |
612 | while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) { | 613 | speed = freq_pos->frequency; |
613 | speed = longhaul_table[j].frequency; | ||
614 | if (speed > min_vid_speed) | 614 | if (speed > min_vid_speed) |
615 | pos = (speed - min_vid_speed) / kHz_step + minvid.pos; | 615 | pos = (speed - min_vid_speed) / kHz_step + minvid.pos; |
616 | else | 616 | else |
617 | pos = minvid.pos; | 617 | pos = minvid.pos; |
618 | longhaul_table[j].driver_data |= mV_vrm_table[pos] << 8; | 618 | freq_pos->driver_data |= mV_vrm_table[pos] << 8; |
619 | vid = vrm_mV_table[mV_vrm_table[pos]]; | 619 | vid = vrm_mV_table[mV_vrm_table[pos]]; |
620 | printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n", | 620 | printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n", |
621 | speed, j, vid.mV); | 621 | speed, (int)(freq_pos - longhaul_table), vid.mV); |
622 | j++; | ||
623 | } | 622 | } |
624 | 623 | ||
625 | can_scale_voltage = 1; | 624 | can_scale_voltage = 1; |
diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c index 84c84b5f0f3a..35dd4d7ffee0 100644 --- a/drivers/cpufreq/pasemi-cpufreq.c +++ b/drivers/cpufreq/pasemi-cpufreq.c | |||
@@ -136,9 +136,10 @@ void restore_astate(int cpu) | |||
136 | 136 | ||
137 | static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) | 137 | static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) |
138 | { | 138 | { |
139 | struct cpufreq_frequency_table *pos; | ||
139 | const u32 *max_freqp; | 140 | const u32 *max_freqp; |
140 | u32 max_freq; | 141 | u32 max_freq; |
141 | int i, cur_astate; | 142 | int cur_astate; |
142 | struct resource res; | 143 | struct resource res; |
143 | struct device_node *cpu, *dn; | 144 | struct device_node *cpu, *dn; |
144 | int err = -ENODEV; | 145 | int err = -ENODEV; |
@@ -197,10 +198,9 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
197 | pr_debug("initializing frequency table\n"); | 198 | pr_debug("initializing frequency table\n"); |
198 | 199 | ||
199 | /* initialize frequency table */ | 200 | /* initialize frequency table */ |
200 | for (i=0; pas_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) { | 201 | cpufreq_for_each_entry(pos, pas_freqs) { |
201 | pas_freqs[i].frequency = | 202 | pos->frequency = get_astate_freq(pos->driver_data) * 100000; |
202 | get_astate_freq(pas_freqs[i].driver_data) * 100000; | 203 | pr_debug("%d: %d\n", (int)(pos - pas_freqs), pos->frequency); |
203 | pr_debug("%d: %d\n", i, pas_freqs[i].frequency); | ||
204 | } | 204 | } |
205 | 205 | ||
206 | cur_astate = get_cur_astate(policy->cpu); | 206 | cur_astate = get_cur_astate(policy->cpu); |
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index 78904e6ca4a0..c8012bc86910 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c | |||
@@ -151,6 +151,7 @@ static int powernow_k6_target(struct cpufreq_policy *policy, | |||
151 | 151 | ||
152 | static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | 152 | static int powernow_k6_cpu_init(struct cpufreq_policy *policy) |
153 | { | 153 | { |
154 | struct cpufreq_frequency_table *pos; | ||
154 | unsigned int i, f; | 155 | unsigned int i, f; |
155 | unsigned khz; | 156 | unsigned khz; |
156 | 157 | ||
@@ -168,12 +169,11 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | |||
168 | } | 169 | } |
169 | } | 170 | } |
170 | if (param_max_multiplier) { | 171 | if (param_max_multiplier) { |
171 | for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { | 172 | cpufreq_for_each_entry(pos, clock_ratio) |
172 | if (clock_ratio[i].driver_data == param_max_multiplier) { | 173 | if (pos->driver_data == param_max_multiplier) { |
173 | max_multiplier = param_max_multiplier; | 174 | max_multiplier = param_max_multiplier; |
174 | goto have_max_multiplier; | 175 | goto have_max_multiplier; |
175 | } | 176 | } |
176 | } | ||
177 | printk(KERN_ERR "powernow-k6: invalid max_multiplier parameter, valid parameters 20, 30, 35, 40, 45, 50, 55, 60\n"); | 177 | printk(KERN_ERR "powernow-k6: invalid max_multiplier parameter, valid parameters 20, 30, 35, 40, 45, 50, 55, 60\n"); |
178 | return -EINVAL; | 178 | return -EINVAL; |
179 | } | 179 | } |
@@ -201,12 +201,12 @@ have_busfreq: | |||
201 | param_busfreq = busfreq * 10; | 201 | param_busfreq = busfreq * 10; |
202 | 202 | ||
203 | /* table init */ | 203 | /* table init */ |
204 | for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { | 204 | cpufreq_for_each_entry(pos, clock_ratio) { |
205 | f = clock_ratio[i].driver_data; | 205 | f = pos->driver_data; |
206 | if (f > max_multiplier) | 206 | if (f > max_multiplier) |
207 | clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID; | 207 | pos->frequency = CPUFREQ_ENTRY_INVALID; |
208 | else | 208 | else |
209 | clock_ratio[i].frequency = busfreq * f; | 209 | pos->frequency = busfreq * f; |
210 | } | 210 | } |
211 | 211 | ||
212 | /* cpuinfo and default policy values */ | 212 | /* cpuinfo and default policy values */ |
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 1b6ae6b57c11..f9ce7e4bf0fe 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c | |||
@@ -27,6 +27,8 @@ | |||
27 | * power and thermal data sheets, (e.g. 30417.pdf, 30430.pdf, 43375.pdf) | 27 | * power and thermal data sheets, (e.g. 30417.pdf, 30430.pdf, 43375.pdf) |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
31 | |||
30 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
31 | #include <linux/smp.h> | 33 | #include <linux/smp.h> |
32 | #include <linux/module.h> | 34 | #include <linux/module.h> |
@@ -45,7 +47,6 @@ | |||
45 | #include <linux/mutex.h> | 47 | #include <linux/mutex.h> |
46 | #include <acpi/processor.h> | 48 | #include <acpi/processor.h> |
47 | 49 | ||
48 | #define PFX "powernow-k8: " | ||
49 | #define VERSION "version 2.20.00" | 50 | #define VERSION "version 2.20.00" |
50 | #include "powernow-k8.h" | 51 | #include "powernow-k8.h" |
51 | 52 | ||
@@ -161,7 +162,7 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid) | |||
161 | u32 i = 0; | 162 | u32 i = 0; |
162 | 163 | ||
163 | if ((fid & INVALID_FID_MASK) || (data->currvid & INVALID_VID_MASK)) { | 164 | if ((fid & INVALID_FID_MASK) || (data->currvid & INVALID_VID_MASK)) { |
164 | printk(KERN_ERR PFX "internal error - overflow on fid write\n"); | 165 | pr_err("internal error - overflow on fid write\n"); |
165 | return 1; | 166 | return 1; |
166 | } | 167 | } |
167 | 168 | ||
@@ -175,9 +176,7 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid) | |||
175 | do { | 176 | do { |
176 | wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION); | 177 | wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION); |
177 | if (i++ > 100) { | 178 | if (i++ > 100) { |
178 | printk(KERN_ERR PFX | 179 | pr_err("Hardware error - pending bit very stuck - no further pstate changes possible\n"); |
179 | "Hardware error - pending bit very stuck - " | ||
180 | "no further pstate changes possible\n"); | ||
181 | return 1; | 180 | return 1; |
182 | } | 181 | } |
183 | } while (query_current_values_with_pending_wait(data)); | 182 | } while (query_current_values_with_pending_wait(data)); |
@@ -185,15 +184,13 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid) | |||
185 | count_off_irt(data); | 184 | count_off_irt(data); |
186 | 185 | ||
187 | if (savevid != data->currvid) { | 186 | if (savevid != data->currvid) { |
188 | printk(KERN_ERR PFX | 187 | pr_err("vid change on fid trans, old 0x%x, new 0x%x\n", |
189 | "vid change on fid trans, old 0x%x, new 0x%x\n", | 188 | savevid, data->currvid); |
190 | savevid, data->currvid); | ||
191 | return 1; | 189 | return 1; |
192 | } | 190 | } |
193 | 191 | ||
194 | if (fid != data->currfid) { | 192 | if (fid != data->currfid) { |
195 | printk(KERN_ERR PFX | 193 | pr_err("fid trans failed, fid 0x%x, curr 0x%x\n", fid, |
196 | "fid trans failed, fid 0x%x, curr 0x%x\n", fid, | ||
197 | data->currfid); | 194 | data->currfid); |
198 | return 1; | 195 | return 1; |
199 | } | 196 | } |
@@ -209,7 +206,7 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid) | |||
209 | int i = 0; | 206 | int i = 0; |
210 | 207 | ||
211 | if ((data->currfid & INVALID_FID_MASK) || (vid & INVALID_VID_MASK)) { | 208 | if ((data->currfid & INVALID_FID_MASK) || (vid & INVALID_VID_MASK)) { |
212 | printk(KERN_ERR PFX "internal error - overflow on vid write\n"); | 209 | pr_err("internal error - overflow on vid write\n"); |
213 | return 1; | 210 | return 1; |
214 | } | 211 | } |
215 | 212 | ||
@@ -223,23 +220,19 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid) | |||
223 | do { | 220 | do { |
224 | wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS); | 221 | wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS); |
225 | if (i++ > 100) { | 222 | if (i++ > 100) { |
226 | printk(KERN_ERR PFX "internal error - pending bit " | 223 | pr_err("internal error - pending bit very stuck - no further pstate changes possible\n"); |
227 | "very stuck - no further pstate " | ||
228 | "changes possible\n"); | ||
229 | return 1; | 224 | return 1; |
230 | } | 225 | } |
231 | } while (query_current_values_with_pending_wait(data)); | 226 | } while (query_current_values_with_pending_wait(data)); |
232 | 227 | ||
233 | if (savefid != data->currfid) { | 228 | if (savefid != data->currfid) { |
234 | printk(KERN_ERR PFX "fid changed on vid trans, old " | 229 | pr_err("fid changed on vid trans, old 0x%x new 0x%x\n", |
235 | "0x%x new 0x%x\n", | 230 | savefid, data->currfid); |
236 | savefid, data->currfid); | ||
237 | return 1; | 231 | return 1; |
238 | } | 232 | } |
239 | 233 | ||
240 | if (vid != data->currvid) { | 234 | if (vid != data->currvid) { |
241 | printk(KERN_ERR PFX "vid trans failed, vid 0x%x, " | 235 | pr_err("vid trans failed, vid 0x%x, curr 0x%x\n", |
242 | "curr 0x%x\n", | ||
243 | vid, data->currvid); | 236 | vid, data->currvid); |
244 | return 1; | 237 | return 1; |
245 | } | 238 | } |
@@ -283,8 +276,7 @@ static int transition_fid_vid(struct powernow_k8_data *data, | |||
283 | return 1; | 276 | return 1; |
284 | 277 | ||
285 | if ((reqfid != data->currfid) || (reqvid != data->currvid)) { | 278 | if ((reqfid != data->currfid) || (reqvid != data->currvid)) { |
286 | printk(KERN_ERR PFX "failed (cpu%d): req 0x%x 0x%x, " | 279 | pr_err("failed (cpu%d): req 0x%x 0x%x, curr 0x%x 0x%x\n", |
287 | "curr 0x%x 0x%x\n", | ||
288 | smp_processor_id(), | 280 | smp_processor_id(), |
289 | reqfid, reqvid, data->currfid, data->currvid); | 281 | reqfid, reqvid, data->currfid, data->currvid); |
290 | return 1; | 282 | return 1; |
@@ -304,8 +296,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, | |||
304 | u32 savefid = data->currfid; | 296 | u32 savefid = data->currfid; |
305 | u32 maxvid, lo, rvomult = 1; | 297 | u32 maxvid, lo, rvomult = 1; |
306 | 298 | ||
307 | pr_debug("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, " | 299 | pr_debug("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n", |
308 | "reqvid 0x%x, rvo 0x%x\n", | ||
309 | smp_processor_id(), | 300 | smp_processor_id(), |
310 | data->currfid, data->currvid, reqvid, data->rvo); | 301 | data->currfid, data->currvid, reqvid, data->rvo); |
311 | 302 | ||
@@ -342,8 +333,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, | |||
342 | return 1; | 333 | return 1; |
343 | 334 | ||
344 | if (savefid != data->currfid) { | 335 | if (savefid != data->currfid) { |
345 | printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n", | 336 | pr_err("ph1 err, currfid changed 0x%x\n", data->currfid); |
346 | data->currfid); | ||
347 | return 1; | 337 | return 1; |
348 | } | 338 | } |
349 | 339 | ||
@@ -360,13 +350,11 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | |||
360 | u32 fid_interval, savevid = data->currvid; | 350 | u32 fid_interval, savevid = data->currvid; |
361 | 351 | ||
362 | if (data->currfid == reqfid) { | 352 | if (data->currfid == reqfid) { |
363 | printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n", | 353 | pr_err("ph2 null fid transition 0x%x\n", data->currfid); |
364 | data->currfid); | ||
365 | return 0; | 354 | return 0; |
366 | } | 355 | } |
367 | 356 | ||
368 | pr_debug("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, " | 357 | pr_debug("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, reqfid 0x%x\n", |
369 | "reqfid 0x%x\n", | ||
370 | smp_processor_id(), | 358 | smp_processor_id(), |
371 | data->currfid, data->currvid, reqfid); | 359 | data->currfid, data->currvid, reqfid); |
372 | 360 | ||
@@ -409,15 +397,13 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | |||
409 | return 1; | 397 | return 1; |
410 | 398 | ||
411 | if (data->currfid != reqfid) { | 399 | if (data->currfid != reqfid) { |
412 | printk(KERN_ERR PFX | 400 | pr_err("ph2: mismatch, failed fid transition, curr 0x%x, req 0x%x\n", |
413 | "ph2: mismatch, failed fid transition, " | ||
414 | "curr 0x%x, req 0x%x\n", | ||
415 | data->currfid, reqfid); | 401 | data->currfid, reqfid); |
416 | return 1; | 402 | return 1; |
417 | } | 403 | } |
418 | 404 | ||
419 | if (savevid != data->currvid) { | 405 | if (savevid != data->currvid) { |
420 | printk(KERN_ERR PFX "ph2: vid changed, save 0x%x, curr 0x%x\n", | 406 | pr_err("ph2: vid changed, save 0x%x, curr 0x%x\n", |
421 | savevid, data->currvid); | 407 | savevid, data->currvid); |
422 | return 1; | 408 | return 1; |
423 | } | 409 | } |
@@ -444,17 +430,14 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, | |||
444 | return 1; | 430 | return 1; |
445 | 431 | ||
446 | if (savefid != data->currfid) { | 432 | if (savefid != data->currfid) { |
447 | printk(KERN_ERR PFX | 433 | pr_err("ph3: bad fid change, save 0x%x, curr 0x%x\n", |
448 | "ph3: bad fid change, save 0x%x, curr 0x%x\n", | 434 | savefid, data->currfid); |
449 | savefid, data->currfid); | ||
450 | return 1; | 435 | return 1; |
451 | } | 436 | } |
452 | 437 | ||
453 | if (data->currvid != reqvid) { | 438 | if (data->currvid != reqvid) { |
454 | printk(KERN_ERR PFX | 439 | pr_err("ph3: failed vid transition\n, req 0x%x, curr 0x%x", |
455 | "ph3: failed vid transition\n, " | 440 | reqvid, data->currvid); |
456 | "req 0x%x, curr 0x%x", | ||
457 | reqvid, data->currvid); | ||
458 | return 1; | 441 | return 1; |
459 | } | 442 | } |
460 | } | 443 | } |
@@ -498,23 +481,20 @@ static void check_supported_cpu(void *_rc) | |||
498 | if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { | 481 | if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { |
499 | if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || | 482 | if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || |
500 | ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) { | 483 | ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) { |
501 | printk(KERN_INFO PFX | 484 | pr_info("Processor cpuid %x not supported\n", eax); |
502 | "Processor cpuid %x not supported\n", eax); | ||
503 | return; | 485 | return; |
504 | } | 486 | } |
505 | 487 | ||
506 | eax = cpuid_eax(CPUID_GET_MAX_CAPABILITIES); | 488 | eax = cpuid_eax(CPUID_GET_MAX_CAPABILITIES); |
507 | if (eax < CPUID_FREQ_VOLT_CAPABILITIES) { | 489 | if (eax < CPUID_FREQ_VOLT_CAPABILITIES) { |
508 | printk(KERN_INFO PFX | 490 | pr_info("No frequency change capabilities detected\n"); |
509 | "No frequency change capabilities detected\n"); | ||
510 | return; | 491 | return; |
511 | } | 492 | } |
512 | 493 | ||
513 | cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx); | 494 | cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx); |
514 | if ((edx & P_STATE_TRANSITION_CAPABLE) | 495 | if ((edx & P_STATE_TRANSITION_CAPABLE) |
515 | != P_STATE_TRANSITION_CAPABLE) { | 496 | != P_STATE_TRANSITION_CAPABLE) { |
516 | printk(KERN_INFO PFX | 497 | pr_info("Power state transitions not supported\n"); |
517 | "Power state transitions not supported\n"); | ||
518 | return; | 498 | return; |
519 | } | 499 | } |
520 | *rc = 0; | 500 | *rc = 0; |
@@ -529,43 +509,39 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, | |||
529 | 509 | ||
530 | for (j = 0; j < data->numps; j++) { | 510 | for (j = 0; j < data->numps; j++) { |
531 | if (pst[j].vid > LEAST_VID) { | 511 | if (pst[j].vid > LEAST_VID) { |
532 | printk(KERN_ERR FW_BUG PFX "vid %d invalid : 0x%x\n", | 512 | pr_err(FW_BUG "vid %d invalid : 0x%x\n", j, |
533 | j, pst[j].vid); | 513 | pst[j].vid); |
534 | return -EINVAL; | 514 | return -EINVAL; |
535 | } | 515 | } |
536 | if (pst[j].vid < data->rvo) { | 516 | if (pst[j].vid < data->rvo) { |
537 | /* vid + rvo >= 0 */ | 517 | /* vid + rvo >= 0 */ |
538 | printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate" | 518 | pr_err(FW_BUG "0 vid exceeded with pstate %d\n", j); |
539 | " %d\n", j); | ||
540 | return -ENODEV; | 519 | return -ENODEV; |
541 | } | 520 | } |
542 | if (pst[j].vid < maxvid + data->rvo) { | 521 | if (pst[j].vid < maxvid + data->rvo) { |
543 | /* vid + rvo >= maxvid */ | 522 | /* vid + rvo >= maxvid */ |
544 | printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate" | 523 | pr_err(FW_BUG "maxvid exceeded with pstate %d\n", j); |
545 | " %d\n", j); | ||
546 | return -ENODEV; | 524 | return -ENODEV; |
547 | } | 525 | } |
548 | if (pst[j].fid > MAX_FID) { | 526 | if (pst[j].fid > MAX_FID) { |
549 | printk(KERN_ERR FW_BUG PFX "maxfid exceeded with pstate" | 527 | pr_err(FW_BUG "maxfid exceeded with pstate %d\n", j); |
550 | " %d\n", j); | ||
551 | return -ENODEV; | 528 | return -ENODEV; |
552 | } | 529 | } |
553 | if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) { | 530 | if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) { |
554 | /* Only first fid is allowed to be in "low" range */ | 531 | /* Only first fid is allowed to be in "low" range */ |
555 | printk(KERN_ERR FW_BUG PFX "two low fids - %d : " | 532 | pr_err(FW_BUG "two low fids - %d : 0x%x\n", j, |
556 | "0x%x\n", j, pst[j].fid); | 533 | pst[j].fid); |
557 | return -EINVAL; | 534 | return -EINVAL; |
558 | } | 535 | } |
559 | if (pst[j].fid < lastfid) | 536 | if (pst[j].fid < lastfid) |
560 | lastfid = pst[j].fid; | 537 | lastfid = pst[j].fid; |
561 | } | 538 | } |
562 | if (lastfid & 1) { | 539 | if (lastfid & 1) { |
563 | printk(KERN_ERR FW_BUG PFX "lastfid invalid\n"); | 540 | pr_err(FW_BUG "lastfid invalid\n"); |
564 | return -EINVAL; | 541 | return -EINVAL; |
565 | } | 542 | } |
566 | if (lastfid > LO_FID_TABLE_TOP) | 543 | if (lastfid > LO_FID_TABLE_TOP) |
567 | printk(KERN_INFO FW_BUG PFX | 544 | pr_info(FW_BUG "first fid not from lo freq table\n"); |
568 | "first fid not from lo freq table\n"); | ||
569 | 545 | ||
570 | return 0; | 546 | return 0; |
571 | } | 547 | } |
@@ -582,16 +558,14 @@ static void print_basics(struct powernow_k8_data *data) | |||
582 | for (j = 0; j < data->numps; j++) { | 558 | for (j = 0; j < data->numps; j++) { |
583 | if (data->powernow_table[j].frequency != | 559 | if (data->powernow_table[j].frequency != |
584 | CPUFREQ_ENTRY_INVALID) { | 560 | CPUFREQ_ENTRY_INVALID) { |
585 | printk(KERN_INFO PFX | 561 | pr_info("fid 0x%x (%d MHz), vid 0x%x\n", |
586 | "fid 0x%x (%d MHz), vid 0x%x\n", | 562 | data->powernow_table[j].driver_data & 0xff, |
587 | data->powernow_table[j].driver_data & 0xff, | 563 | data->powernow_table[j].frequency/1000, |
588 | data->powernow_table[j].frequency/1000, | 564 | data->powernow_table[j].driver_data >> 8); |
589 | data->powernow_table[j].driver_data >> 8); | ||
590 | } | 565 | } |
591 | } | 566 | } |
592 | if (data->batps) | 567 | if (data->batps) |
593 | printk(KERN_INFO PFX "Only %d pstates on battery\n", | 568 | pr_info("Only %d pstates on battery\n", data->batps); |
594 | data->batps); | ||
595 | } | 569 | } |
596 | 570 | ||
597 | static int fill_powernow_table(struct powernow_k8_data *data, | 571 | static int fill_powernow_table(struct powernow_k8_data *data, |
@@ -602,21 +576,20 @@ static int fill_powernow_table(struct powernow_k8_data *data, | |||
602 | 576 | ||
603 | if (data->batps) { | 577 | if (data->batps) { |
604 | /* use ACPI support to get full speed on mains power */ | 578 | /* use ACPI support to get full speed on mains power */ |
605 | printk(KERN_WARNING PFX | 579 | pr_warn("Only %d pstates usable (use ACPI driver for full range\n", |
606 | "Only %d pstates usable (use ACPI driver for full " | 580 | data->batps); |
607 | "range\n", data->batps); | ||
608 | data->numps = data->batps; | 581 | data->numps = data->batps; |
609 | } | 582 | } |
610 | 583 | ||
611 | for (j = 1; j < data->numps; j++) { | 584 | for (j = 1; j < data->numps; j++) { |
612 | if (pst[j-1].fid >= pst[j].fid) { | 585 | if (pst[j-1].fid >= pst[j].fid) { |
613 | printk(KERN_ERR PFX "PST out of sequence\n"); | 586 | pr_err("PST out of sequence\n"); |
614 | return -EINVAL; | 587 | return -EINVAL; |
615 | } | 588 | } |
616 | } | 589 | } |
617 | 590 | ||
618 | if (data->numps < 2) { | 591 | if (data->numps < 2) { |
619 | printk(KERN_ERR PFX "no p states to transition\n"); | 592 | pr_err("no p states to transition\n"); |
620 | return -ENODEV; | 593 | return -ENODEV; |
621 | } | 594 | } |
622 | 595 | ||
@@ -626,7 +599,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, | |||
626 | powernow_table = kzalloc((sizeof(*powernow_table) | 599 | powernow_table = kzalloc((sizeof(*powernow_table) |
627 | * (data->numps + 1)), GFP_KERNEL); | 600 | * (data->numps + 1)), GFP_KERNEL); |
628 | if (!powernow_table) { | 601 | if (!powernow_table) { |
629 | printk(KERN_ERR PFX "powernow_table memory alloc failure\n"); | 602 | pr_err("powernow_table memory alloc failure\n"); |
630 | return -ENOMEM; | 603 | return -ENOMEM; |
631 | } | 604 | } |
632 | 605 | ||
@@ -681,13 +654,13 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
681 | 654 | ||
682 | pr_debug("table vers: 0x%x\n", psb->tableversion); | 655 | pr_debug("table vers: 0x%x\n", psb->tableversion); |
683 | if (psb->tableversion != PSB_VERSION_1_4) { | 656 | if (psb->tableversion != PSB_VERSION_1_4) { |
684 | printk(KERN_ERR FW_BUG PFX "PSB table is not v1.4\n"); | 657 | pr_err(FW_BUG "PSB table is not v1.4\n"); |
685 | return -ENODEV; | 658 | return -ENODEV; |
686 | } | 659 | } |
687 | 660 | ||
688 | pr_debug("flags: 0x%x\n", psb->flags1); | 661 | pr_debug("flags: 0x%x\n", psb->flags1); |
689 | if (psb->flags1) { | 662 | if (psb->flags1) { |
690 | printk(KERN_ERR FW_BUG PFX "unknown flags\n"); | 663 | pr_err(FW_BUG "unknown flags\n"); |
691 | return -ENODEV; | 664 | return -ENODEV; |
692 | } | 665 | } |
693 | 666 | ||
@@ -716,7 +689,7 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
716 | cpst = 1; | 689 | cpst = 1; |
717 | } | 690 | } |
718 | if (cpst != 1) { | 691 | if (cpst != 1) { |
719 | printk(KERN_ERR FW_BUG PFX "numpst must be 1\n"); | 692 | pr_err(FW_BUG "numpst must be 1\n"); |
720 | return -ENODEV; | 693 | return -ENODEV; |
721 | } | 694 | } |
722 | 695 | ||
@@ -742,9 +715,8 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
742 | * BIOS and Kernel Developer's Guide, which is available on | 715 | * BIOS and Kernel Developer's Guide, which is available on |
743 | * www.amd.com | 716 | * www.amd.com |
744 | */ | 717 | */ |
745 | printk(KERN_ERR FW_BUG PFX "No PSB or ACPI _PSS objects\n"); | 718 | pr_err(FW_BUG "No PSB or ACPI _PSS objects\n"); |
746 | printk(KERN_ERR PFX "Make sure that your BIOS is up to date" | 719 | pr_err("Make sure that your BIOS is up to date and Cool'N'Quiet support is enabled in BIOS setup\n"); |
747 | " and Cool'N'Quiet support is enabled in BIOS setup\n"); | ||
748 | return -ENODEV; | 720 | return -ENODEV; |
749 | } | 721 | } |
750 | 722 | ||
@@ -819,8 +791,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
819 | acpi_processor_notify_smm(THIS_MODULE); | 791 | acpi_processor_notify_smm(THIS_MODULE); |
820 | 792 | ||
821 | if (!zalloc_cpumask_var(&data->acpi_data.shared_cpu_map, GFP_KERNEL)) { | 793 | if (!zalloc_cpumask_var(&data->acpi_data.shared_cpu_map, GFP_KERNEL)) { |
822 | printk(KERN_ERR PFX | 794 | pr_err("unable to alloc powernow_k8_data cpumask\n"); |
823 | "unable to alloc powernow_k8_data cpumask\n"); | ||
824 | ret_val = -ENOMEM; | 795 | ret_val = -ENOMEM; |
825 | goto err_out_mem; | 796 | goto err_out_mem; |
826 | } | 797 | } |
@@ -885,9 +856,8 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, | |||
885 | } | 856 | } |
886 | 857 | ||
887 | if (freq != (data->acpi_data.states[i].core_frequency * 1000)) { | 858 | if (freq != (data->acpi_data.states[i].core_frequency * 1000)) { |
888 | printk(KERN_INFO PFX "invalid freq entries " | 859 | pr_info("invalid freq entries %u kHz vs. %u kHz\n", |
889 | "%u kHz vs. %u kHz\n", freq, | 860 | freq, (unsigned int) |
890 | (unsigned int) | ||
891 | (data->acpi_data.states[i].core_frequency | 861 | (data->acpi_data.states[i].core_frequency |
892 | * 1000)); | 862 | * 1000)); |
893 | invalidate_entry(powernow_table, i); | 863 | invalidate_entry(powernow_table, i); |
@@ -916,7 +886,7 @@ static int get_transition_latency(struct powernow_k8_data *data) | |||
916 | max_latency = cur_latency; | 886 | max_latency = cur_latency; |
917 | } | 887 | } |
918 | if (max_latency == 0) { | 888 | if (max_latency == 0) { |
919 | pr_err(FW_WARN PFX "Invalid zero transition latency\n"); | 889 | pr_err(FW_WARN "Invalid zero transition latency\n"); |
920 | max_latency = 1; | 890 | max_latency = 1; |
921 | } | 891 | } |
922 | /* value in usecs, needs to be in nanoseconds */ | 892 | /* value in usecs, needs to be in nanoseconds */ |
@@ -991,7 +961,7 @@ static long powernowk8_target_fn(void *arg) | |||
991 | checkvid = data->currvid; | 961 | checkvid = data->currvid; |
992 | 962 | ||
993 | if (pending_bit_stuck()) { | 963 | if (pending_bit_stuck()) { |
994 | printk(KERN_ERR PFX "failing targ, change pending bit set\n"); | 964 | pr_err("failing targ, change pending bit set\n"); |
995 | return -EIO; | 965 | return -EIO; |
996 | } | 966 | } |
997 | 967 | ||
@@ -1003,12 +973,11 @@ static long powernowk8_target_fn(void *arg) | |||
1003 | return -EIO; | 973 | return -EIO; |
1004 | 974 | ||
1005 | pr_debug("targ: curr fid 0x%x, vid 0x%x\n", | 975 | pr_debug("targ: curr fid 0x%x, vid 0x%x\n", |
1006 | data->currfid, data->currvid); | 976 | data->currfid, data->currvid); |
1007 | 977 | ||
1008 | if ((checkvid != data->currvid) || | 978 | if ((checkvid != data->currvid) || |
1009 | (checkfid != data->currfid)) { | 979 | (checkfid != data->currfid)) { |
1010 | pr_info(PFX | 980 | pr_info("error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n", |
1011 | "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n", | ||
1012 | checkfid, data->currfid, | 981 | checkfid, data->currfid, |
1013 | checkvid, data->currvid); | 982 | checkvid, data->currvid); |
1014 | } | 983 | } |
@@ -1020,7 +989,7 @@ static long powernowk8_target_fn(void *arg) | |||
1020 | ret = transition_frequency_fidvid(data, newstate); | 989 | ret = transition_frequency_fidvid(data, newstate); |
1021 | 990 | ||
1022 | if (ret) { | 991 | if (ret) { |
1023 | printk(KERN_ERR PFX "transition frequency failed\n"); | 992 | pr_err("transition frequency failed\n"); |
1024 | mutex_unlock(&fidvid_mutex); | 993 | mutex_unlock(&fidvid_mutex); |
1025 | return 1; | 994 | return 1; |
1026 | } | 995 | } |
@@ -1049,7 +1018,7 @@ static void powernowk8_cpu_init_on_cpu(void *_init_on_cpu) | |||
1049 | struct init_on_cpu *init_on_cpu = _init_on_cpu; | 1018 | struct init_on_cpu *init_on_cpu = _init_on_cpu; |
1050 | 1019 | ||
1051 | if (pending_bit_stuck()) { | 1020 | if (pending_bit_stuck()) { |
1052 | printk(KERN_ERR PFX "failing init, change pending bit set\n"); | 1021 | pr_err("failing init, change pending bit set\n"); |
1053 | init_on_cpu->rc = -ENODEV; | 1022 | init_on_cpu->rc = -ENODEV; |
1054 | return; | 1023 | return; |
1055 | } | 1024 | } |
@@ -1064,11 +1033,10 @@ static void powernowk8_cpu_init_on_cpu(void *_init_on_cpu) | |||
1064 | init_on_cpu->rc = 0; | 1033 | init_on_cpu->rc = 0; |
1065 | } | 1034 | } |
1066 | 1035 | ||
1067 | static const char missing_pss_msg[] = | 1036 | #define MISSING_PSS_MSG \ |
1068 | KERN_ERR | 1037 | FW_BUG "No compatible ACPI _PSS objects found.\n" \ |
1069 | FW_BUG PFX "No compatible ACPI _PSS objects found.\n" | 1038 | FW_BUG "First, make sure Cool'N'Quiet is enabled in the BIOS.\n" \ |
1070 | FW_BUG PFX "First, make sure Cool'N'Quiet is enabled in the BIOS.\n" | 1039 | FW_BUG "If that doesn't help, try upgrading your BIOS.\n" |
1071 | FW_BUG PFX "If that doesn't help, try upgrading your BIOS.\n"; | ||
1072 | 1040 | ||
1073 | /* per CPU init entry point to the driver */ | 1041 | /* per CPU init entry point to the driver */ |
1074 | static int powernowk8_cpu_init(struct cpufreq_policy *pol) | 1042 | static int powernowk8_cpu_init(struct cpufreq_policy *pol) |
@@ -1083,7 +1051,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1083 | 1051 | ||
1084 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 1052 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
1085 | if (!data) { | 1053 | if (!data) { |
1086 | printk(KERN_ERR PFX "unable to alloc powernow_k8_data"); | 1054 | pr_err("unable to alloc powernow_k8_data"); |
1087 | return -ENOMEM; | 1055 | return -ENOMEM; |
1088 | } | 1056 | } |
1089 | 1057 | ||
@@ -1095,13 +1063,11 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1095 | * an UP version, and is deprecated by AMD. | 1063 | * an UP version, and is deprecated by AMD. |
1096 | */ | 1064 | */ |
1097 | if (num_online_cpus() != 1) { | 1065 | if (num_online_cpus() != 1) { |
1098 | printk_once(missing_pss_msg); | 1066 | pr_err_once(MISSING_PSS_MSG); |
1099 | goto err_out; | 1067 | goto err_out; |
1100 | } | 1068 | } |
1101 | if (pol->cpu != 0) { | 1069 | if (pol->cpu != 0) { |
1102 | printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " | 1070 | pr_err(FW_BUG "No ACPI _PSS objects for CPU other than CPU0. Complain to your BIOS vendor.\n"); |
1103 | "CPU other than CPU0. Complain to your BIOS " | ||
1104 | "vendor.\n"); | ||
1105 | goto err_out; | 1071 | goto err_out; |
1106 | } | 1072 | } |
1107 | rc = find_psb_table(data); | 1073 | rc = find_psb_table(data); |
@@ -1129,7 +1095,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1129 | 1095 | ||
1130 | /* min/max the cpu is capable of */ | 1096 | /* min/max the cpu is capable of */ |
1131 | if (cpufreq_table_validate_and_show(pol, data->powernow_table)) { | 1097 | if (cpufreq_table_validate_and_show(pol, data->powernow_table)) { |
1132 | printk(KERN_ERR FW_BUG PFX "invalid powernow_table\n"); | 1098 | pr_err(FW_BUG "invalid powernow_table\n"); |
1133 | powernow_k8_cpu_exit_acpi(data); | 1099 | powernow_k8_cpu_exit_acpi(data); |
1134 | kfree(data->powernow_table); | 1100 | kfree(data->powernow_table); |
1135 | kfree(data); | 1101 | kfree(data); |
@@ -1137,7 +1103,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1137 | } | 1103 | } |
1138 | 1104 | ||
1139 | pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n", | 1105 | pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n", |
1140 | data->currfid, data->currvid); | 1106 | data->currfid, data->currvid); |
1141 | 1107 | ||
1142 | /* Point all the CPUs in this policy to the same data */ | 1108 | /* Point all the CPUs in this policy to the same data */ |
1143 | for_each_cpu(cpu, pol->cpus) | 1109 | for_each_cpu(cpu, pol->cpus) |
@@ -1220,12 +1186,12 @@ static void __request_acpi_cpufreq(void) | |||
1220 | goto request; | 1186 | goto request; |
1221 | 1187 | ||
1222 | if (strncmp(cur_drv, drv, min_t(size_t, strlen(cur_drv), strlen(drv)))) | 1188 | if (strncmp(cur_drv, drv, min_t(size_t, strlen(cur_drv), strlen(drv)))) |
1223 | pr_warn(PFX "WTF driver: %s\n", cur_drv); | 1189 | pr_warn("WTF driver: %s\n", cur_drv); |
1224 | 1190 | ||
1225 | return; | 1191 | return; |
1226 | 1192 | ||
1227 | request: | 1193 | request: |
1228 | pr_warn(PFX "This CPU is not supported anymore, using acpi-cpufreq instead.\n"); | 1194 | pr_warn("This CPU is not supported anymore, using acpi-cpufreq instead.\n"); |
1229 | request_module(drv); | 1195 | request_module(drv); |
1230 | } | 1196 | } |
1231 | 1197 | ||
@@ -1260,7 +1226,7 @@ static int powernowk8_init(void) | |||
1260 | if (ret) | 1226 | if (ret) |
1261 | return ret; | 1227 | return ret; |
1262 | 1228 | ||
1263 | pr_info(PFX "Found %d %s (%d cpu cores) (" VERSION ")\n", | 1229 | pr_info("Found %d %s (%d cpu cores) (" VERSION ")\n", |
1264 | num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus); | 1230 | num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus); |
1265 | 1231 | ||
1266 | return ret; | 1232 | return ret; |
@@ -1274,8 +1240,8 @@ static void __exit powernowk8_exit(void) | |||
1274 | cpufreq_unregister_driver(&cpufreq_amd64_driver); | 1240 | cpufreq_unregister_driver(&cpufreq_amd64_driver); |
1275 | } | 1241 | } |
1276 | 1242 | ||
1277 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and " | 1243 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com>"); |
1278 | "Mark Langsdorf <mark.langsdorf@amd.com>"); | 1244 | MODULE_AUTHOR("Mark Langsdorf <mark.langsdorf@amd.com>"); |
1279 | MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); | 1245 | MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); |
1280 | MODULE_LICENSE("GPL"); | 1246 | MODULE_LICENSE("GPL"); |
1281 | 1247 | ||
diff --git a/drivers/cpufreq/powernow-k8.h b/drivers/cpufreq/powernow-k8.h index 79329d4d5abe..45ce11e86626 100644 --- a/drivers/cpufreq/powernow-k8.h +++ b/drivers/cpufreq/powernow-k8.h | |||
@@ -19,7 +19,7 @@ struct powernow_k8_data { | |||
19 | u32 vidmvs; /* usable value calculated from mvs */ | 19 | u32 vidmvs; /* usable value calculated from mvs */ |
20 | u32 vstable; /* voltage stabilization time, units 20 us */ | 20 | u32 vstable; /* voltage stabilization time, units 20 us */ |
21 | u32 plllock; /* pll lock time, units 1 us */ | 21 | u32 plllock; /* pll lock time, units 1 us */ |
22 | u32 exttype; /* extended interface = 1 */ | 22 | u32 exttype; /* extended interface = 1 */ |
23 | 23 | ||
24 | /* keep track of the current fid / vid or pstate */ | 24 | /* keep track of the current fid / vid or pstate */ |
25 | u32 currvid; | 25 | u32 currvid; |
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index af4968813e76..bb1d08dc8cc8 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c | |||
@@ -235,7 +235,7 @@ static void powernv_read_cpu_freq(void *arg) | |||
235 | * firmware for CPU 'cpu'. This value is reported through the sysfs | 235 | * firmware for CPU 'cpu'. This value is reported through the sysfs |
236 | * file cpuinfo_cur_freq. | 236 | * file cpuinfo_cur_freq. |
237 | */ | 237 | */ |
238 | unsigned int powernv_cpufreq_get(unsigned int cpu) | 238 | static unsigned int powernv_cpufreq_get(unsigned int cpu) |
239 | { | 239 | { |
240 | struct powernv_smp_call_data freq_data; | 240 | struct powernv_smp_call_data freq_data; |
241 | 241 | ||
diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c index 5be8a48dba74..5a4c5a639f61 100644 --- a/drivers/cpufreq/ppc_cbe_cpufreq.c +++ b/drivers/cpufreq/ppc_cbe_cpufreq.c | |||
@@ -67,9 +67,10 @@ static int set_pmode(unsigned int cpu, unsigned int slow_mode) | |||
67 | 67 | ||
68 | static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) | 68 | static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) |
69 | { | 69 | { |
70 | struct cpufreq_frequency_table *pos; | ||
70 | const u32 *max_freqp; | 71 | const u32 *max_freqp; |
71 | u32 max_freq; | 72 | u32 max_freq; |
72 | int i, cur_pmode; | 73 | int cur_pmode; |
73 | struct device_node *cpu; | 74 | struct device_node *cpu; |
74 | 75 | ||
75 | cpu = of_get_cpu_node(policy->cpu, NULL); | 76 | cpu = of_get_cpu_node(policy->cpu, NULL); |
@@ -102,9 +103,9 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
102 | pr_debug("initializing frequency table\n"); | 103 | pr_debug("initializing frequency table\n"); |
103 | 104 | ||
104 | /* initialize frequency table */ | 105 | /* initialize frequency table */ |
105 | for (i=0; cbe_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) { | 106 | cpufreq_for_each_entry(pos, cbe_freqs) { |
106 | cbe_freqs[i].frequency = max_freq / cbe_freqs[i].driver_data; | 107 | pos->frequency = max_freq / pos->driver_data; |
107 | pr_debug("%d: %d\n", i, cbe_freqs[i].frequency); | 108 | pr_debug("%d: %d\n", (int)(pos - cbe_freqs), pos->frequency); |
108 | } | 109 | } |
109 | 110 | ||
110 | /* if DEBUG is enabled set_pmode() measures the latency | 111 | /* if DEBUG is enabled set_pmode() measures the latency |
diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c index 4626f90559b5..2fd53eaaec20 100644 --- a/drivers/cpufreq/s3c2416-cpufreq.c +++ b/drivers/cpufreq/s3c2416-cpufreq.c | |||
@@ -266,7 +266,7 @@ out: | |||
266 | static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq) | 266 | static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq) |
267 | { | 267 | { |
268 | int count, v, i, found; | 268 | int count, v, i, found; |
269 | struct cpufreq_frequency_table *freq; | 269 | struct cpufreq_frequency_table *pos; |
270 | struct s3c2416_dvfs *dvfs; | 270 | struct s3c2416_dvfs *dvfs; |
271 | 271 | ||
272 | count = regulator_count_voltages(s3c_freq->vddarm); | 272 | count = regulator_count_voltages(s3c_freq->vddarm); |
@@ -275,12 +275,11 @@ static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq) | |||
275 | return; | 275 | return; |
276 | } | 276 | } |
277 | 277 | ||
278 | freq = s3c_freq->freq_table; | 278 | if (!count) |
279 | while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) { | 279 | goto out; |
280 | if (freq->frequency == CPUFREQ_ENTRY_INVALID) | ||
281 | continue; | ||
282 | 280 | ||
283 | dvfs = &s3c2416_dvfs_table[freq->driver_data]; | 281 | cpufreq_for_each_valid_entry(pos, s3c_freq->freq_table) { |
282 | dvfs = &s3c2416_dvfs_table[pos->driver_data]; | ||
284 | found = 0; | 283 | found = 0; |
285 | 284 | ||
286 | /* Check only the min-voltage, more is always ok on S3C2416 */ | 285 | /* Check only the min-voltage, more is always ok on S3C2416 */ |
@@ -292,13 +291,12 @@ static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq) | |||
292 | 291 | ||
293 | if (!found) { | 292 | if (!found) { |
294 | pr_debug("cpufreq: %dkHz unsupported by regulator\n", | 293 | pr_debug("cpufreq: %dkHz unsupported by regulator\n", |
295 | freq->frequency); | 294 | pos->frequency); |
296 | freq->frequency = CPUFREQ_ENTRY_INVALID; | 295 | pos->frequency = CPUFREQ_ENTRY_INVALID; |
297 | } | 296 | } |
298 | |||
299 | freq++; | ||
300 | } | 297 | } |
301 | 298 | ||
299 | out: | ||
302 | /* Guessed */ | 300 | /* Guessed */ |
303 | s3c_freq->regulator_latency = 1 * 1000 * 1000; | 301 | s3c_freq->regulator_latency = 1 * 1000 * 1000; |
304 | } | 302 | } |
@@ -338,7 +336,7 @@ static struct notifier_block s3c2416_cpufreq_reboot_notifier = { | |||
338 | static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy) | 336 | static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy) |
339 | { | 337 | { |
340 | struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; | 338 | struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; |
341 | struct cpufreq_frequency_table *freq; | 339 | struct cpufreq_frequency_table *pos; |
342 | struct clk *msysclk; | 340 | struct clk *msysclk; |
343 | unsigned long rate; | 341 | unsigned long rate; |
344 | int ret; | 342 | int ret; |
@@ -427,31 +425,27 @@ static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
427 | s3c_freq->regulator_latency = 0; | 425 | s3c_freq->regulator_latency = 0; |
428 | #endif | 426 | #endif |
429 | 427 | ||
430 | freq = s3c_freq->freq_table; | 428 | cpufreq_for_each_entry(pos, s3c_freq->freq_table) { |
431 | while (freq->frequency != CPUFREQ_TABLE_END) { | ||
432 | /* special handling for dvs mode */ | 429 | /* special handling for dvs mode */ |
433 | if (freq->driver_data == 0) { | 430 | if (pos->driver_data == 0) { |
434 | if (!s3c_freq->hclk) { | 431 | if (!s3c_freq->hclk) { |
435 | pr_debug("cpufreq: %dkHz unsupported as it would need unavailable dvs mode\n", | 432 | pr_debug("cpufreq: %dkHz unsupported as it would need unavailable dvs mode\n", |
436 | freq->frequency); | 433 | pos->frequency); |
437 | freq->frequency = CPUFREQ_ENTRY_INVALID; | 434 | pos->frequency = CPUFREQ_ENTRY_INVALID; |
438 | } else { | 435 | } else { |
439 | freq++; | ||
440 | continue; | 436 | continue; |
441 | } | 437 | } |
442 | } | 438 | } |
443 | 439 | ||
444 | /* Check for frequencies we can generate */ | 440 | /* Check for frequencies we can generate */ |
445 | rate = clk_round_rate(s3c_freq->armdiv, | 441 | rate = clk_round_rate(s3c_freq->armdiv, |
446 | freq->frequency * 1000); | 442 | pos->frequency * 1000); |
447 | rate /= 1000; | 443 | rate /= 1000; |
448 | if (rate != freq->frequency) { | 444 | if (rate != pos->frequency) { |
449 | pr_debug("cpufreq: %dkHz unsupported by clock (clk_round_rate return %lu)\n", | 445 | pr_debug("cpufreq: %dkHz unsupported by clock (clk_round_rate return %lu)\n", |
450 | freq->frequency, rate); | 446 | pos->frequency, rate); |
451 | freq->frequency = CPUFREQ_ENTRY_INVALID; | 447 | pos->frequency = CPUFREQ_ENTRY_INVALID; |
452 | } | 448 | } |
453 | |||
454 | freq++; | ||
455 | } | 449 | } |
456 | 450 | ||
457 | /* Datasheet says PLL stabalisation time must be at least 300us, | 451 | /* Datasheet says PLL stabalisation time must be at least 300us, |
diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c index ff7d3ecb85f0..176e84cc3991 100644 --- a/drivers/cpufreq/s3c64xx-cpufreq.c +++ b/drivers/cpufreq/s3c64xx-cpufreq.c | |||
@@ -118,11 +118,10 @@ static void __init s3c64xx_cpufreq_config_regulator(void) | |||
118 | pr_err("Unable to check supported voltages\n"); | 118 | pr_err("Unable to check supported voltages\n"); |
119 | } | 119 | } |
120 | 120 | ||
121 | freq = s3c64xx_freq_table; | 121 | if (!count) |
122 | while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) { | 122 | goto out; |
123 | if (freq->frequency == CPUFREQ_ENTRY_INVALID) | ||
124 | continue; | ||
125 | 123 | ||
124 | cpufreq_for_each_valid_entry(freq, s3c64xx_freq_table) { | ||
126 | dvfs = &s3c64xx_dvfs_table[freq->driver_data]; | 125 | dvfs = &s3c64xx_dvfs_table[freq->driver_data]; |
127 | found = 0; | 126 | found = 0; |
128 | 127 | ||
@@ -137,10 +136,9 @@ static void __init s3c64xx_cpufreq_config_regulator(void) | |||
137 | freq->frequency); | 136 | freq->frequency); |
138 | freq->frequency = CPUFREQ_ENTRY_INVALID; | 137 | freq->frequency = CPUFREQ_ENTRY_INVALID; |
139 | } | 138 | } |
140 | |||
141 | freq++; | ||
142 | } | 139 | } |
143 | 140 | ||
141 | out: | ||
144 | /* Guess based on having to do an I2C/SPI write; in future we | 142 | /* Guess based on having to do an I2C/SPI write; in future we |
145 | * will be able to query the regulator performance here. */ | 143 | * will be able to query the regulator performance here. */ |
146 | regulator_latency = 1 * 1000 * 1000; | 144 | regulator_latency = 1 * 1000 * 1000; |
@@ -179,8 +177,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
179 | } | 177 | } |
180 | #endif | 178 | #endif |
181 | 179 | ||
182 | freq = s3c64xx_freq_table; | 180 | cpufreq_for_each_entry(freq, s3c64xx_freq_table) { |
183 | while (freq->frequency != CPUFREQ_TABLE_END) { | ||
184 | unsigned long r; | 181 | unsigned long r; |
185 | 182 | ||
186 | /* Check for frequencies we can generate */ | 183 | /* Check for frequencies we can generate */ |
@@ -196,8 +193,6 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
196 | * frequency is the maximum we can support. */ | 193 | * frequency is the maximum we can support. */ |
197 | if (!vddarm && freq->frequency > clk_get_rate(policy->clk) / 1000) | 194 | if (!vddarm && freq->frequency > clk_get_rate(policy->clk) / 1000) |
198 | freq->frequency = CPUFREQ_ENTRY_INVALID; | 195 | freq->frequency = CPUFREQ_ENTRY_INVALID; |
199 | |||
200 | freq++; | ||
201 | } | 196 | } |
202 | 197 | ||
203 | /* Datasheet says PLL stabalisation time (if we were to use | 198 | /* Datasheet says PLL stabalisation time (if we were to use |
diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index ab2c1a40d437..19a10b89fef7 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c | |||
@@ -175,10 +175,8 @@ static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) | |||
175 | mutex_lock(&set_freq_lock); | 175 | mutex_lock(&set_freq_lock); |
176 | 176 | ||
177 | if (no_cpufreq_access) { | 177 | if (no_cpufreq_access) { |
178 | #ifdef CONFIG_PM_VERBOSE | 178 | pr_err("Denied access to %s as it is disabled temporarily\n", |
179 | pr_err("%s:%d denied access to %s as it is disabled" | 179 | __func__); |
180 | "temporarily\n", __FILE__, __LINE__, __func__); | ||
181 | #endif | ||
182 | ret = -EINVAL; | 180 | ret = -EINVAL; |
183 | goto exit; | 181 | goto exit; |
184 | } | 182 | } |
diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c index 6723f0390f20..7d4a31571608 100644 --- a/drivers/cpufreq/speedstep-centrino.c +++ b/drivers/cpufreq/speedstep-centrino.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <asm/cpu_device_id.h> | 28 | #include <asm/cpu_device_id.h> |
29 | 29 | ||
30 | #define PFX "speedstep-centrino: " | 30 | #define PFX "speedstep-centrino: " |
31 | #define MAINTAINER "cpufreq@vger.kernel.org" | 31 | #define MAINTAINER "linux-pm@vger.kernel.org" |
32 | 32 | ||
33 | #define INTEL_MSR_RANGE (0xffff) | 33 | #define INTEL_MSR_RANGE (0xffff) |
34 | 34 | ||
diff --git a/drivers/cpufreq/tegra-cpufreq.c b/drivers/cpufreq/tegra-cpufreq.c index 63f00598a251..6e774c6ac20b 100644 --- a/drivers/cpufreq/tegra-cpufreq.c +++ b/drivers/cpufreq/tegra-cpufreq.c | |||
@@ -82,9 +82,9 @@ out: | |||
82 | return ret; | 82 | return ret; |
83 | } | 83 | } |
84 | 84 | ||
85 | static int tegra_update_cpu_speed(struct cpufreq_policy *policy, | 85 | static int tegra_target(struct cpufreq_policy *policy, unsigned int index) |
86 | unsigned long rate) | ||
87 | { | 86 | { |
87 | unsigned long rate = freq_table[index].frequency; | ||
88 | int ret = 0; | 88 | int ret = 0; |
89 | 89 | ||
90 | /* | 90 | /* |
@@ -106,11 +106,6 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy, | |||
106 | return ret; | 106 | return ret; |
107 | } | 107 | } |
108 | 108 | ||
109 | static int tegra_target(struct cpufreq_policy *policy, unsigned int index) | ||
110 | { | ||
111 | return tegra_update_cpu_speed(policy, freq_table[index].frequency); | ||
112 | } | ||
113 | |||
114 | static int tegra_cpu_init(struct cpufreq_policy *policy) | 109 | static int tegra_cpu_init(struct cpufreq_policy *policy) |
115 | { | 110 | { |
116 | int ret; | 111 | int ret; |
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm index ae1d78ea7df7..b6d69e899f5d 100644 --- a/drivers/cpuidle/Kconfig.arm +++ b/drivers/cpuidle/Kconfig.arm | |||
@@ -18,6 +18,12 @@ config ARM_BIG_LITTLE_CPUIDLE | |||
18 | define different C-states for little and big cores through the | 18 | define different C-states for little and big cores through the |
19 | multiple CPU idle drivers infrastructure. | 19 | multiple CPU idle drivers infrastructure. |
20 | 20 | ||
21 | config ARM_CLPS711X_CPUIDLE | ||
22 | bool "CPU Idle Driver for CLPS711X processors" | ||
23 | depends on ARCH_CLPS711X || COMPILE_TEST | ||
24 | help | ||
25 | Select this to enable cpuidle on Cirrus Logic CLPS711X SOCs. | ||
26 | |||
21 | config ARM_HIGHBANK_CPUIDLE | 27 | config ARM_HIGHBANK_CPUIDLE |
22 | bool "CPU Idle Driver for Calxeda processors" | 28 | bool "CPU Idle Driver for Calxeda processors" |
23 | depends on ARM_PSCI | 29 | depends on ARM_PSCI |
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile index cd3ab59f8461..9b5b2b560d70 100644 --- a/drivers/cpuidle/Makefile +++ b/drivers/cpuidle/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o | |||
9 | # ARM SoC drivers | 9 | # ARM SoC drivers |
10 | obj-$(CONFIG_ARM_ARMADA_370_XP_CPUIDLE) += cpuidle-armada-370-xp.o | 10 | obj-$(CONFIG_ARM_ARMADA_370_XP_CPUIDLE) += cpuidle-armada-370-xp.o |
11 | obj-$(CONFIG_ARM_BIG_LITTLE_CPUIDLE) += cpuidle-big_little.o | 11 | obj-$(CONFIG_ARM_BIG_LITTLE_CPUIDLE) += cpuidle-big_little.o |
12 | obj-$(CONFIG_ARM_CLPS711X_CPUIDLE) += cpuidle-clps711x.o | ||
12 | obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE) += cpuidle-calxeda.o | 13 | obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE) += cpuidle-calxeda.o |
13 | obj-$(CONFIG_ARM_KIRKWOOD_CPUIDLE) += cpuidle-kirkwood.o | 14 | obj-$(CONFIG_ARM_KIRKWOOD_CPUIDLE) += cpuidle-kirkwood.o |
14 | obj-$(CONFIG_ARM_ZYNQ_CPUIDLE) += cpuidle-zynq.o | 15 | obj-$(CONFIG_ARM_ZYNQ_CPUIDLE) += cpuidle-zynq.o |
diff --git a/drivers/cpuidle/cpuidle-clps711x.c b/drivers/cpuidle/cpuidle-clps711x.c new file mode 100644 index 000000000000..5243811daa6e --- /dev/null +++ b/drivers/cpuidle/cpuidle-clps711x.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * CLPS711X CPU idle driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/cpuidle.h> | ||
13 | #include <linux/err.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #define CLPS711X_CPUIDLE_NAME "clps711x-cpuidle" | ||
19 | |||
20 | static void __iomem *clps711x_halt; | ||
21 | |||
22 | static int clps711x_cpuidle_halt(struct cpuidle_device *dev, | ||
23 | struct cpuidle_driver *drv, int index) | ||
24 | { | ||
25 | writel(0xaa, clps711x_halt); | ||
26 | |||
27 | return index; | ||
28 | } | ||
29 | |||
30 | static struct cpuidle_driver clps711x_idle_driver = { | ||
31 | .name = CLPS711X_CPUIDLE_NAME, | ||
32 | .owner = THIS_MODULE, | ||
33 | .states[0] = { | ||
34 | .name = "HALT", | ||
35 | .desc = "CLPS711X HALT", | ||
36 | .enter = clps711x_cpuidle_halt, | ||
37 | .exit_latency = 1, | ||
38 | }, | ||
39 | .state_count = 1, | ||
40 | }; | ||
41 | |||
42 | static int __init clps711x_cpuidle_probe(struct platform_device *pdev) | ||
43 | { | ||
44 | struct resource *res; | ||
45 | |||
46 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
47 | clps711x_halt = devm_ioremap_resource(&pdev->dev, res); | ||
48 | if (IS_ERR(clps711x_halt)) | ||
49 | return PTR_ERR(clps711x_halt); | ||
50 | |||
51 | return cpuidle_register(&clps711x_idle_driver, NULL); | ||
52 | } | ||
53 | |||
54 | static struct platform_driver clps711x_cpuidle_driver = { | ||
55 | .driver = { | ||
56 | .name = CLPS711X_CPUIDLE_NAME, | ||
57 | .owner = THIS_MODULE, | ||
58 | }, | ||
59 | }; | ||
60 | module_platform_driver_probe(clps711x_cpuidle_driver, clps711x_cpuidle_probe); | ||
61 | |||
62 | MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); | ||
63 | MODULE_DESCRIPTION("CLPS711X CPU idle driver"); | ||
64 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 7d2f43550700..49e74c1fc639 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig | |||
@@ -70,19 +70,20 @@ config ARM_EXYNOS4_BUS_DEVFREQ | |||
70 | depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM | 70 | depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM |
71 | select ARCH_HAS_OPP | 71 | select ARCH_HAS_OPP |
72 | select DEVFREQ_GOV_SIMPLE_ONDEMAND | 72 | select DEVFREQ_GOV_SIMPLE_ONDEMAND |
73 | select PM_OPP | ||
73 | help | 74 | help |
74 | This adds the DEVFREQ driver for Exynos4210 memory bus (vdd_int) | 75 | This adds the DEVFREQ driver for Exynos4210 memory bus (vdd_int) |
75 | and Exynos4212/4412 memory interface and bus (vdd_mif + vdd_int). | 76 | and Exynos4212/4412 memory interface and bus (vdd_mif + vdd_int). |
76 | It reads PPMU counters of memory controllers and adjusts | 77 | It reads PPMU counters of memory controllers and adjusts |
77 | the operating frequencies and voltages with OPP support. | 78 | the operating frequencies and voltages with OPP support. |
78 | To operate with optimal voltages, ASV support is required | 79 | This does not yet operate with optimal voltages. |
79 | (CONFIG_EXYNOS_ASV). | ||
80 | 80 | ||
81 | config ARM_EXYNOS5_BUS_DEVFREQ | 81 | config ARM_EXYNOS5_BUS_DEVFREQ |
82 | bool "ARM Exynos5250 Bus DEVFREQ Driver" | 82 | bool "ARM Exynos5250 Bus DEVFREQ Driver" |
83 | depends on SOC_EXYNOS5250 | 83 | depends on SOC_EXYNOS5250 |
84 | select ARCH_HAS_OPP | 84 | select ARCH_HAS_OPP |
85 | select DEVFREQ_GOV_SIMPLE_ONDEMAND | 85 | select DEVFREQ_GOV_SIMPLE_ONDEMAND |
86 | select PM_OPP | ||
86 | help | 87 | help |
87 | This adds the DEVFREQ driver for Exynos5250 bus interface (vdd_int). | 88 | This adds the DEVFREQ driver for Exynos5250 bus interface (vdd_int). |
88 | It reads PPMU counters of memory controllers and adjusts the | 89 | It reads PPMU counters of memory controllers and adjusts the |
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 2042ec3656ba..9f90369dd6bd 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c | |||
@@ -394,7 +394,7 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type, | |||
394 | * @devfreq: the devfreq struct | 394 | * @devfreq: the devfreq struct |
395 | * @skip: skip calling device_unregister(). | 395 | * @skip: skip calling device_unregister(). |
396 | */ | 396 | */ |
397 | static void _remove_devfreq(struct devfreq *devfreq, bool skip) | 397 | static void _remove_devfreq(struct devfreq *devfreq) |
398 | { | 398 | { |
399 | mutex_lock(&devfreq_list_lock); | 399 | mutex_lock(&devfreq_list_lock); |
400 | if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) { | 400 | if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) { |
@@ -412,11 +412,6 @@ static void _remove_devfreq(struct devfreq *devfreq, bool skip) | |||
412 | if (devfreq->profile->exit) | 412 | if (devfreq->profile->exit) |
413 | devfreq->profile->exit(devfreq->dev.parent); | 413 | devfreq->profile->exit(devfreq->dev.parent); |
414 | 414 | ||
415 | if (!skip && get_device(&devfreq->dev)) { | ||
416 | device_unregister(&devfreq->dev); | ||
417 | put_device(&devfreq->dev); | ||
418 | } | ||
419 | |||
420 | mutex_destroy(&devfreq->lock); | 415 | mutex_destroy(&devfreq->lock); |
421 | kfree(devfreq); | 416 | kfree(devfreq); |
422 | } | 417 | } |
@@ -426,14 +421,12 @@ static void _remove_devfreq(struct devfreq *devfreq, bool skip) | |||
426 | * @dev: the devfreq device | 421 | * @dev: the devfreq device |
427 | * | 422 | * |
428 | * This calls _remove_devfreq() if _remove_devfreq() is not called. | 423 | * This calls _remove_devfreq() if _remove_devfreq() is not called. |
429 | * Note that devfreq_dev_release() could be called by _remove_devfreq() as | ||
430 | * well as by others unregistering the device. | ||
431 | */ | 424 | */ |
432 | static void devfreq_dev_release(struct device *dev) | 425 | static void devfreq_dev_release(struct device *dev) |
433 | { | 426 | { |
434 | struct devfreq *devfreq = to_devfreq(dev); | 427 | struct devfreq *devfreq = to_devfreq(dev); |
435 | 428 | ||
436 | _remove_devfreq(devfreq, true); | 429 | _remove_devfreq(devfreq); |
437 | } | 430 | } |
438 | 431 | ||
439 | /** | 432 | /** |
@@ -544,12 +537,76 @@ int devfreq_remove_device(struct devfreq *devfreq) | |||
544 | if (!devfreq) | 537 | if (!devfreq) |
545 | return -EINVAL; | 538 | return -EINVAL; |
546 | 539 | ||
547 | _remove_devfreq(devfreq, false); | 540 | device_unregister(&devfreq->dev); |
541 | put_device(&devfreq->dev); | ||
548 | 542 | ||
549 | return 0; | 543 | return 0; |
550 | } | 544 | } |
551 | EXPORT_SYMBOL(devfreq_remove_device); | 545 | EXPORT_SYMBOL(devfreq_remove_device); |
552 | 546 | ||
547 | static int devm_devfreq_dev_match(struct device *dev, void *res, void *data) | ||
548 | { | ||
549 | struct devfreq **r = res; | ||
550 | |||
551 | if (WARN_ON(!r || !*r)) | ||
552 | return 0; | ||
553 | |||
554 | return *r == data; | ||
555 | } | ||
556 | |||
557 | static void devm_devfreq_dev_release(struct device *dev, void *res) | ||
558 | { | ||
559 | devfreq_remove_device(*(struct devfreq **)res); | ||
560 | } | ||
561 | |||
562 | /** | ||
563 | * devm_devfreq_add_device() - Resource-managed devfreq_add_device() | ||
564 | * @dev: the device to add devfreq feature. | ||
565 | * @profile: device-specific profile to run devfreq. | ||
566 | * @governor_name: name of the policy to choose frequency. | ||
567 | * @data: private data for the governor. The devfreq framework does not | ||
568 | * touch this value. | ||
569 | * | ||
570 | * This function manages automatically the memory of devfreq device using device | ||
571 | * resource management and simplify the free operation for memory of devfreq | ||
572 | * device. | ||
573 | */ | ||
574 | struct devfreq *devm_devfreq_add_device(struct device *dev, | ||
575 | struct devfreq_dev_profile *profile, | ||
576 | const char *governor_name, | ||
577 | void *data) | ||
578 | { | ||
579 | struct devfreq **ptr, *devfreq; | ||
580 | |||
581 | ptr = devres_alloc(devm_devfreq_dev_release, sizeof(*ptr), GFP_KERNEL); | ||
582 | if (!ptr) | ||
583 | return ERR_PTR(-ENOMEM); | ||
584 | |||
585 | devfreq = devfreq_add_device(dev, profile, governor_name, data); | ||
586 | if (IS_ERR(devfreq)) { | ||
587 | devres_free(ptr); | ||
588 | return ERR_PTR(-ENOMEM); | ||
589 | } | ||
590 | |||
591 | *ptr = devfreq; | ||
592 | devres_add(dev, ptr); | ||
593 | |||
594 | return devfreq; | ||
595 | } | ||
596 | EXPORT_SYMBOL(devm_devfreq_add_device); | ||
597 | |||
598 | /** | ||
599 | * devm_devfreq_remove_device() - Resource-managed devfreq_remove_device() | ||
600 | * @dev: the device to add devfreq feature. | ||
601 | * @devfreq: the devfreq instance to be removed | ||
602 | */ | ||
603 | void devm_devfreq_remove_device(struct device *dev, struct devfreq *devfreq) | ||
604 | { | ||
605 | WARN_ON(devres_release(dev, devm_devfreq_dev_release, | ||
606 | devm_devfreq_dev_match, devfreq)); | ||
607 | } | ||
608 | EXPORT_SYMBOL(devm_devfreq_remove_device); | ||
609 | |||
553 | /** | 610 | /** |
554 | * devfreq_suspend_device() - Suspend devfreq of a device. | 611 | * devfreq_suspend_device() - Suspend devfreq of a device. |
555 | * @devfreq: the devfreq instance to be suspended | 612 | * @devfreq: the devfreq instance to be suspended |
@@ -1112,6 +1169,54 @@ int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq) | |||
1112 | return ret; | 1169 | return ret; |
1113 | } | 1170 | } |
1114 | 1171 | ||
1172 | static void devm_devfreq_opp_release(struct device *dev, void *res) | ||
1173 | { | ||
1174 | devfreq_unregister_opp_notifier(dev, *(struct devfreq **)res); | ||
1175 | } | ||
1176 | |||
1177 | /** | ||
1178 | * devm_ devfreq_register_opp_notifier() | ||
1179 | * - Resource-managed devfreq_register_opp_notifier() | ||
1180 | * @dev: The devfreq user device. (parent of devfreq) | ||
1181 | * @devfreq: The devfreq object. | ||
1182 | */ | ||
1183 | int devm_devfreq_register_opp_notifier(struct device *dev, | ||
1184 | struct devfreq *devfreq) | ||
1185 | { | ||
1186 | struct devfreq **ptr; | ||
1187 | int ret; | ||
1188 | |||
1189 | ptr = devres_alloc(devm_devfreq_opp_release, sizeof(*ptr), GFP_KERNEL); | ||
1190 | if (!ptr) | ||
1191 | return -ENOMEM; | ||
1192 | |||
1193 | ret = devfreq_register_opp_notifier(dev, devfreq); | ||
1194 | if (ret) { | ||
1195 | devres_free(ptr); | ||
1196 | return ret; | ||
1197 | } | ||
1198 | |||
1199 | *ptr = devfreq; | ||
1200 | devres_add(dev, ptr); | ||
1201 | |||
1202 | return 0; | ||
1203 | } | ||
1204 | EXPORT_SYMBOL(devm_devfreq_register_opp_notifier); | ||
1205 | |||
1206 | /** | ||
1207 | * devm_devfreq_unregister_opp_notifier() | ||
1208 | * - Resource-managed devfreq_unregister_opp_notifier() | ||
1209 | * @dev: The devfreq user device. (parent of devfreq) | ||
1210 | * @devfreq: The devfreq object. | ||
1211 | */ | ||
1212 | void devm_devfreq_unregister_opp_notifier(struct device *dev, | ||
1213 | struct devfreq *devfreq) | ||
1214 | { | ||
1215 | WARN_ON(devres_release(dev, devm_devfreq_opp_release, | ||
1216 | devm_devfreq_dev_match, devfreq)); | ||
1217 | } | ||
1218 | EXPORT_SYMBOL(devm_devfreq_unregister_opp_notifier); | ||
1219 | |||
1115 | MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); | 1220 | MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); |
1116 | MODULE_DESCRIPTION("devfreq class support"); | 1221 | MODULE_DESCRIPTION("devfreq class support"); |
1117 | MODULE_LICENSE("GPL"); | 1222 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/devfreq/exynos/Makefile b/drivers/devfreq/exynos/Makefile index bfaaf5b0d61d..49bc9175f923 100644 --- a/drivers/devfreq/exynos/Makefile +++ b/drivers/devfreq/exynos/Makefile | |||
@@ -1,3 +1,3 @@ | |||
1 | # Exynos DEVFREQ Drivers | 1 | # Exynos DEVFREQ Drivers |
2 | obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos4_bus.o | 2 | obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos_ppmu.o exynos4_bus.o |
3 | obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ) += exynos_ppmu.o exynos5_bus.o | 3 | obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ) += exynos_ppmu.o exynos5_bus.o |
diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c index e07b0c68c715..d9b08d3b6830 100644 --- a/drivers/devfreq/exynos/exynos4_bus.c +++ b/drivers/devfreq/exynos/exynos4_bus.c | |||
@@ -25,13 +25,9 @@ | |||
25 | #include <linux/regulator/consumer.h> | 25 | #include <linux/regulator/consumer.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | 27 | ||
28 | /* Exynos4 ASV has been in the mailing list, but not upstreamed, yet. */ | ||
29 | #ifdef CONFIG_EXYNOS_ASV | ||
30 | extern unsigned int exynos_result_of_asv; | ||
31 | #endif | ||
32 | |||
33 | #include <mach/map.h> | 28 | #include <mach/map.h> |
34 | 29 | ||
30 | #include "exynos_ppmu.h" | ||
35 | #include "exynos4_bus.h" | 31 | #include "exynos4_bus.h" |
36 | 32 | ||
37 | #define MAX_SAFEVOLT 1200000 /* 1.2V */ | 33 | #define MAX_SAFEVOLT 1200000 /* 1.2V */ |
@@ -44,22 +40,6 @@ enum exynos4_busf_type { | |||
44 | /* Assume that the bus is saturated if the utilization is 40% */ | 40 | /* Assume that the bus is saturated if the utilization is 40% */ |
45 | #define BUS_SATURATION_RATIO 40 | 41 | #define BUS_SATURATION_RATIO 40 |
46 | 42 | ||
47 | enum ppmu_counter { | ||
48 | PPMU_PMNCNT0 = 0, | ||
49 | PPMU_PMCCNT1, | ||
50 | PPMU_PMNCNT2, | ||
51 | PPMU_PMNCNT3, | ||
52 | PPMU_PMNCNT_MAX, | ||
53 | }; | ||
54 | struct exynos4_ppmu { | ||
55 | void __iomem *hw_base; | ||
56 | unsigned int ccnt; | ||
57 | unsigned int event; | ||
58 | unsigned int count[PPMU_PMNCNT_MAX]; | ||
59 | bool ccnt_overflow; | ||
60 | bool count_overflow[PPMU_PMNCNT_MAX]; | ||
61 | }; | ||
62 | |||
63 | enum busclk_level_idx { | 43 | enum busclk_level_idx { |
64 | LV_0 = 0, | 44 | LV_0 = 0, |
65 | LV_1, | 45 | LV_1, |
@@ -68,6 +48,13 @@ enum busclk_level_idx { | |||
68 | LV_4, | 48 | LV_4, |
69 | _LV_END | 49 | _LV_END |
70 | }; | 50 | }; |
51 | |||
52 | enum exynos_ppmu_idx { | ||
53 | PPMU_DMC0, | ||
54 | PPMU_DMC1, | ||
55 | PPMU_END, | ||
56 | }; | ||
57 | |||
71 | #define EX4210_LV_MAX LV_2 | 58 | #define EX4210_LV_MAX LV_2 |
72 | #define EX4x12_LV_MAX LV_4 | 59 | #define EX4x12_LV_MAX LV_4 |
73 | #define EX4210_LV_NUM (LV_2 + 1) | 60 | #define EX4210_LV_NUM (LV_2 + 1) |
@@ -91,7 +78,7 @@ struct busfreq_data { | |||
91 | struct regulator *vdd_int; | 78 | struct regulator *vdd_int; |
92 | struct regulator *vdd_mif; /* Exynos4412/4212 only */ | 79 | struct regulator *vdd_mif; /* Exynos4412/4212 only */ |
93 | struct busfreq_opp_info curr_oppinfo; | 80 | struct busfreq_opp_info curr_oppinfo; |
94 | struct exynos4_ppmu dmc[2]; | 81 | struct busfreq_ppmu_data ppmu_data; |
95 | 82 | ||
96 | struct notifier_block pm_notifier; | 83 | struct notifier_block pm_notifier; |
97 | struct mutex lock; | 84 | struct mutex lock; |
@@ -101,12 +88,6 @@ struct busfreq_data { | |||
101 | unsigned int top_divtable[_LV_END]; | 88 | unsigned int top_divtable[_LV_END]; |
102 | }; | 89 | }; |
103 | 90 | ||
104 | struct bus_opp_table { | ||
105 | unsigned int idx; | ||
106 | unsigned long clk; | ||
107 | unsigned long volt; | ||
108 | }; | ||
109 | |||
110 | /* 4210 controls clock of mif and voltage of int */ | 91 | /* 4210 controls clock of mif and voltage of int */ |
111 | static struct bus_opp_table exynos4210_busclk_table[] = { | 92 | static struct bus_opp_table exynos4210_busclk_table[] = { |
112 | {LV_0, 400000, 1150000}, | 93 | {LV_0, 400000, 1150000}, |
@@ -524,57 +505,6 @@ static int exynos4x12_set_busclk(struct busfreq_data *data, | |||
524 | return 0; | 505 | return 0; |
525 | } | 506 | } |
526 | 507 | ||
527 | |||
528 | static void busfreq_mon_reset(struct busfreq_data *data) | ||
529 | { | ||
530 | unsigned int i; | ||
531 | |||
532 | for (i = 0; i < 2; i++) { | ||
533 | void __iomem *ppmu_base = data->dmc[i].hw_base; | ||
534 | |||
535 | /* Reset PPMU */ | ||
536 | __raw_writel(0x8000000f, ppmu_base + 0xf010); | ||
537 | __raw_writel(0x8000000f, ppmu_base + 0xf050); | ||
538 | __raw_writel(0x6, ppmu_base + 0xf000); | ||
539 | __raw_writel(0x0, ppmu_base + 0xf100); | ||
540 | |||
541 | /* Set PPMU Event */ | ||
542 | data->dmc[i].event = 0x6; | ||
543 | __raw_writel(((data->dmc[i].event << 12) | 0x1), | ||
544 | ppmu_base + 0xfc); | ||
545 | |||
546 | /* Start PPMU */ | ||
547 | __raw_writel(0x1, ppmu_base + 0xf000); | ||
548 | } | ||
549 | } | ||
550 | |||
551 | static void exynos4_read_ppmu(struct busfreq_data *data) | ||
552 | { | ||
553 | int i, j; | ||
554 | |||
555 | for (i = 0; i < 2; i++) { | ||
556 | void __iomem *ppmu_base = data->dmc[i].hw_base; | ||
557 | u32 overflow; | ||
558 | |||
559 | /* Stop PPMU */ | ||
560 | __raw_writel(0x0, ppmu_base + 0xf000); | ||
561 | |||
562 | /* Update local data from PPMU */ | ||
563 | overflow = __raw_readl(ppmu_base + 0xf050); | ||
564 | |||
565 | data->dmc[i].ccnt = __raw_readl(ppmu_base + 0xf100); | ||
566 | data->dmc[i].ccnt_overflow = overflow & (1 << 31); | ||
567 | |||
568 | for (j = 0; j < PPMU_PMNCNT_MAX; j++) { | ||
569 | data->dmc[i].count[j] = __raw_readl( | ||
570 | ppmu_base + (0xf110 + (0x10 * j))); | ||
571 | data->dmc[i].count_overflow[j] = overflow & (1 << j); | ||
572 | } | ||
573 | } | ||
574 | |||
575 | busfreq_mon_reset(data); | ||
576 | } | ||
577 | |||
578 | static int exynos4x12_get_intspec(unsigned long mifclk) | 508 | static int exynos4x12_get_intspec(unsigned long mifclk) |
579 | { | 509 | { |
580 | int i = 0; | 510 | int i = 0; |
@@ -698,84 +628,35 @@ out: | |||
698 | return err; | 628 | return err; |
699 | } | 629 | } |
700 | 630 | ||
701 | static int exynos4_get_busier_dmc(struct busfreq_data *data) | ||
702 | { | ||
703 | u64 p0 = data->dmc[0].count[0]; | ||
704 | u64 p1 = data->dmc[1].count[0]; | ||
705 | |||
706 | p0 *= data->dmc[1].ccnt; | ||
707 | p1 *= data->dmc[0].ccnt; | ||
708 | |||
709 | if (data->dmc[1].ccnt == 0) | ||
710 | return 0; | ||
711 | |||
712 | if (p0 > p1) | ||
713 | return 0; | ||
714 | return 1; | ||
715 | } | ||
716 | |||
717 | static int exynos4_bus_get_dev_status(struct device *dev, | 631 | static int exynos4_bus_get_dev_status(struct device *dev, |
718 | struct devfreq_dev_status *stat) | 632 | struct devfreq_dev_status *stat) |
719 | { | 633 | { |
720 | struct busfreq_data *data = dev_get_drvdata(dev); | 634 | struct busfreq_data *data = dev_get_drvdata(dev); |
721 | int busier_dmc; | 635 | struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data; |
722 | int cycles_x2 = 2; /* 2 x cycles */ | 636 | int busier; |
723 | void __iomem *addr; | ||
724 | u32 timing; | ||
725 | u32 memctrl; | ||
726 | |||
727 | exynos4_read_ppmu(data); | ||
728 | busier_dmc = exynos4_get_busier_dmc(data); | ||
729 | stat->current_frequency = data->curr_oppinfo.rate; | ||
730 | 637 | ||
731 | if (busier_dmc) | 638 | exynos_read_ppmu(ppmu_data); |
732 | addr = S5P_VA_DMC1; | 639 | busier = exynos_get_busier_ppmu(ppmu_data); |
733 | else | 640 | stat->current_frequency = data->curr_oppinfo.rate; |
734 | addr = S5P_VA_DMC0; | ||
735 | |||
736 | memctrl = __raw_readl(addr + 0x04); /* one of DDR2/3/LPDDR2 */ | ||
737 | timing = __raw_readl(addr + 0x38); /* CL or WL/RL values */ | ||
738 | |||
739 | switch ((memctrl >> 8) & 0xf) { | ||
740 | case 0x4: /* DDR2 */ | ||
741 | cycles_x2 = ((timing >> 16) & 0xf) * 2; | ||
742 | break; | ||
743 | case 0x5: /* LPDDR2 */ | ||
744 | case 0x6: /* DDR3 */ | ||
745 | cycles_x2 = ((timing >> 8) & 0xf) + ((timing >> 0) & 0xf); | ||
746 | break; | ||
747 | default: | ||
748 | pr_err("%s: Unknown Memory Type(%d).\n", __func__, | ||
749 | (memctrl >> 8) & 0xf); | ||
750 | return -EINVAL; | ||
751 | } | ||
752 | 641 | ||
753 | /* Number of cycles spent on memory access */ | 642 | /* Number of cycles spent on memory access */ |
754 | stat->busy_time = data->dmc[busier_dmc].count[0] / 2 * (cycles_x2 + 2); | 643 | stat->busy_time = ppmu_data->ppmu[busier].count[PPMU_PMNCNT3]; |
755 | stat->busy_time *= 100 / BUS_SATURATION_RATIO; | 644 | stat->busy_time *= 100 / BUS_SATURATION_RATIO; |
756 | stat->total_time = data->dmc[busier_dmc].ccnt; | 645 | stat->total_time = ppmu_data->ppmu[busier].ccnt; |
757 | 646 | ||
758 | /* If the counters have overflown, retry */ | 647 | /* If the counters have overflown, retry */ |
759 | if (data->dmc[busier_dmc].ccnt_overflow || | 648 | if (ppmu_data->ppmu[busier].ccnt_overflow || |
760 | data->dmc[busier_dmc].count_overflow[0]) | 649 | ppmu_data->ppmu[busier].count_overflow[0]) |
761 | return -EAGAIN; | 650 | return -EAGAIN; |
762 | 651 | ||
763 | return 0; | 652 | return 0; |
764 | } | 653 | } |
765 | 654 | ||
766 | static void exynos4_bus_exit(struct device *dev) | ||
767 | { | ||
768 | struct busfreq_data *data = dev_get_drvdata(dev); | ||
769 | |||
770 | devfreq_unregister_opp_notifier(dev, data->devfreq); | ||
771 | } | ||
772 | |||
773 | static struct devfreq_dev_profile exynos4_devfreq_profile = { | 655 | static struct devfreq_dev_profile exynos4_devfreq_profile = { |
774 | .initial_freq = 400000, | 656 | .initial_freq = 400000, |
775 | .polling_ms = 50, | 657 | .polling_ms = 50, |
776 | .target = exynos4_bus_target, | 658 | .target = exynos4_bus_target, |
777 | .get_dev_status = exynos4_bus_get_dev_status, | 659 | .get_dev_status = exynos4_bus_get_dev_status, |
778 | .exit = exynos4_bus_exit, | ||
779 | }; | 660 | }; |
780 | 661 | ||
781 | static int exynos4210_init_tables(struct busfreq_data *data) | 662 | static int exynos4210_init_tables(struct busfreq_data *data) |
@@ -837,11 +718,11 @@ static int exynos4210_init_tables(struct busfreq_data *data) | |||
837 | data->top_divtable[i] = tmp; | 718 | data->top_divtable[i] = tmp; |
838 | } | 719 | } |
839 | 720 | ||
840 | #ifdef CONFIG_EXYNOS_ASV | 721 | /* |
841 | tmp = exynos4_result_of_asv; | 722 | * TODO: init tmp based on busfreq_data |
842 | #else | 723 | * (device-tree or platform-data) |
724 | */ | ||
843 | tmp = 0; /* Max voltages for the reliability of the unknown */ | 725 | tmp = 0; /* Max voltages for the reliability of the unknown */ |
844 | #endif | ||
845 | 726 | ||
846 | pr_debug("ASV Group of Exynos4 is %d\n", tmp); | 727 | pr_debug("ASV Group of Exynos4 is %d\n", tmp); |
847 | /* Use merged grouping for voltage */ | 728 | /* Use merged grouping for voltage */ |
@@ -922,11 +803,7 @@ static int exynos4x12_init_tables(struct busfreq_data *data) | |||
922 | data->dmc_divtable[i] = tmp; | 803 | data->dmc_divtable[i] = tmp; |
923 | } | 804 | } |
924 | 805 | ||
925 | #ifdef CONFIG_EXYNOS_ASV | ||
926 | tmp = exynos4_result_of_asv; | ||
927 | #else | ||
928 | tmp = 0; /* Max voltages for the reliability of the unknown */ | 806 | tmp = 0; /* Max voltages for the reliability of the unknown */ |
929 | #endif | ||
930 | 807 | ||
931 | if (tmp > 8) | 808 | if (tmp > 8) |
932 | tmp = 0; | 809 | tmp = 0; |
@@ -1020,6 +897,7 @@ unlock: | |||
1020 | static int exynos4_busfreq_probe(struct platform_device *pdev) | 897 | static int exynos4_busfreq_probe(struct platform_device *pdev) |
1021 | { | 898 | { |
1022 | struct busfreq_data *data; | 899 | struct busfreq_data *data; |
900 | struct busfreq_ppmu_data *ppmu_data; | ||
1023 | struct dev_pm_opp *opp; | 901 | struct dev_pm_opp *opp; |
1024 | struct device *dev = &pdev->dev; | 902 | struct device *dev = &pdev->dev; |
1025 | int err = 0; | 903 | int err = 0; |
@@ -1030,9 +908,19 @@ static int exynos4_busfreq_probe(struct platform_device *pdev) | |||
1030 | return -ENOMEM; | 908 | return -ENOMEM; |
1031 | } | 909 | } |
1032 | 910 | ||
911 | ppmu_data = &data->ppmu_data; | ||
912 | ppmu_data->ppmu_end = PPMU_END; | ||
913 | ppmu_data->ppmu = devm_kzalloc(dev, | ||
914 | sizeof(struct exynos_ppmu) * PPMU_END, | ||
915 | GFP_KERNEL); | ||
916 | if (!ppmu_data->ppmu) { | ||
917 | dev_err(dev, "Failed to allocate memory for exynos_ppmu\n"); | ||
918 | return -ENOMEM; | ||
919 | } | ||
920 | |||
1033 | data->type = pdev->id_entry->driver_data; | 921 | data->type = pdev->id_entry->driver_data; |
1034 | data->dmc[0].hw_base = S5P_VA_DMC0; | 922 | ppmu_data->ppmu[PPMU_DMC0].hw_base = S5P_VA_DMC0; |
1035 | data->dmc[1].hw_base = S5P_VA_DMC1; | 923 | ppmu_data->ppmu[PPMU_DMC1].hw_base = S5P_VA_DMC1; |
1036 | data->pm_notifier.notifier_call = exynos4_busfreq_pm_notifier_event; | 924 | data->pm_notifier.notifier_call = exynos4_busfreq_pm_notifier_event; |
1037 | data->dev = dev; | 925 | data->dev = dev; |
1038 | mutex_init(&data->lock); | 926 | mutex_init(&data->lock); |
@@ -1048,8 +936,11 @@ static int exynos4_busfreq_probe(struct platform_device *pdev) | |||
1048 | dev_err(dev, "Cannot determine the device id %d\n", data->type); | 936 | dev_err(dev, "Cannot determine the device id %d\n", data->type); |
1049 | err = -EINVAL; | 937 | err = -EINVAL; |
1050 | } | 938 | } |
1051 | if (err) | 939 | if (err) { |
940 | dev_err(dev, "Cannot initialize busfreq table %d\n", | ||
941 | data->type); | ||
1052 | return err; | 942 | return err; |
943 | } | ||
1053 | 944 | ||
1054 | data->vdd_int = devm_regulator_get(dev, "vdd_int"); | 945 | data->vdd_int = devm_regulator_get(dev, "vdd_int"); |
1055 | if (IS_ERR(data->vdd_int)) { | 946 | if (IS_ERR(data->vdd_int)) { |
@@ -1079,19 +970,28 @@ static int exynos4_busfreq_probe(struct platform_device *pdev) | |||
1079 | 970 | ||
1080 | platform_set_drvdata(pdev, data); | 971 | platform_set_drvdata(pdev, data); |
1081 | 972 | ||
1082 | busfreq_mon_reset(data); | 973 | data->devfreq = devm_devfreq_add_device(dev, &exynos4_devfreq_profile, |
1083 | |||
1084 | data->devfreq = devfreq_add_device(dev, &exynos4_devfreq_profile, | ||
1085 | "simple_ondemand", NULL); | 974 | "simple_ondemand", NULL); |
1086 | if (IS_ERR(data->devfreq)) | 975 | if (IS_ERR(data->devfreq)) |
1087 | return PTR_ERR(data->devfreq); | 976 | return PTR_ERR(data->devfreq); |
1088 | 977 | ||
1089 | devfreq_register_opp_notifier(dev, data->devfreq); | 978 | /* |
979 | * Start PPMU (Performance Profiling Monitoring Unit) to check | ||
980 | * utilization of each IP in the Exynos4 SoC. | ||
981 | */ | ||
982 | busfreq_mon_reset(ppmu_data); | ||
1090 | 983 | ||
984 | /* Register opp_notifier for Exynos4 busfreq */ | ||
985 | err = devm_devfreq_register_opp_notifier(dev, data->devfreq); | ||
986 | if (err < 0) { | ||
987 | dev_err(dev, "Failed to register opp notifier\n"); | ||
988 | return err; | ||
989 | } | ||
990 | |||
991 | /* Register pm_notifier for Exynos4 busfreq */ | ||
1091 | err = register_pm_notifier(&data->pm_notifier); | 992 | err = register_pm_notifier(&data->pm_notifier); |
1092 | if (err) { | 993 | if (err) { |
1093 | dev_err(dev, "Failed to setup pm notifier\n"); | 994 | dev_err(dev, "Failed to setup pm notifier\n"); |
1094 | devfreq_remove_device(data->devfreq); | ||
1095 | return err; | 995 | return err; |
1096 | } | 996 | } |
1097 | 997 | ||
@@ -1102,23 +1002,24 @@ static int exynos4_busfreq_remove(struct platform_device *pdev) | |||
1102 | { | 1002 | { |
1103 | struct busfreq_data *data = platform_get_drvdata(pdev); | 1003 | struct busfreq_data *data = platform_get_drvdata(pdev); |
1104 | 1004 | ||
1005 | /* Unregister all of notifier chain */ | ||
1105 | unregister_pm_notifier(&data->pm_notifier); | 1006 | unregister_pm_notifier(&data->pm_notifier); |
1106 | devfreq_remove_device(data->devfreq); | ||
1107 | 1007 | ||
1108 | return 0; | 1008 | return 0; |
1109 | } | 1009 | } |
1110 | 1010 | ||
1011 | #ifdef CONFIG_PM_SLEEP | ||
1111 | static int exynos4_busfreq_resume(struct device *dev) | 1012 | static int exynos4_busfreq_resume(struct device *dev) |
1112 | { | 1013 | { |
1113 | struct busfreq_data *data = dev_get_drvdata(dev); | 1014 | struct busfreq_data *data = dev_get_drvdata(dev); |
1015 | struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data; | ||
1114 | 1016 | ||
1115 | busfreq_mon_reset(data); | 1017 | busfreq_mon_reset(ppmu_data); |
1116 | return 0; | 1018 | return 0; |
1117 | } | 1019 | } |
1020 | #endif | ||
1118 | 1021 | ||
1119 | static const struct dev_pm_ops exynos4_busfreq_pm = { | 1022 | static SIMPLE_DEV_PM_OPS(exynos4_busfreq_pm_ops, NULL, exynos4_busfreq_resume); |
1120 | .resume = exynos4_busfreq_resume, | ||
1121 | }; | ||
1122 | 1023 | ||
1123 | static const struct platform_device_id exynos4_busfreq_id[] = { | 1024 | static const struct platform_device_id exynos4_busfreq_id[] = { |
1124 | { "exynos4210-busfreq", TYPE_BUSF_EXYNOS4210 }, | 1025 | { "exynos4210-busfreq", TYPE_BUSF_EXYNOS4210 }, |
@@ -1134,7 +1035,7 @@ static struct platform_driver exynos4_busfreq_driver = { | |||
1134 | .driver = { | 1035 | .driver = { |
1135 | .name = "exynos4-busfreq", | 1036 | .name = "exynos4-busfreq", |
1136 | .owner = THIS_MODULE, | 1037 | .owner = THIS_MODULE, |
1137 | .pm = &exynos4_busfreq_pm, | 1038 | .pm = &exynos4_busfreq_pm_ops, |
1138 | }, | 1039 | }, |
1139 | }; | 1040 | }; |
1140 | 1041 | ||
diff --git a/drivers/devfreq/exynos/exynos5_bus.c b/drivers/devfreq/exynos/exynos5_bus.c index 6eef1f7397c6..6cd0392e2798 100644 --- a/drivers/devfreq/exynos/exynos5_bus.c +++ b/drivers/devfreq/exynos/exynos5_bus.c | |||
@@ -50,7 +50,7 @@ struct busfreq_data_int { | |||
50 | struct device *dev; | 50 | struct device *dev; |
51 | struct devfreq *devfreq; | 51 | struct devfreq *devfreq; |
52 | struct regulator *vdd_int; | 52 | struct regulator *vdd_int; |
53 | struct exynos_ppmu ppmu[PPMU_END]; | 53 | struct busfreq_ppmu_data ppmu_data; |
54 | unsigned long curr_freq; | 54 | unsigned long curr_freq; |
55 | bool disabled; | 55 | bool disabled; |
56 | 56 | ||
@@ -75,49 +75,6 @@ static struct int_bus_opp_table exynos5_int_opp_table[] = { | |||
75 | {0, 0, 0}, | 75 | {0, 0, 0}, |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static void busfreq_mon_reset(struct busfreq_data_int *data) | ||
79 | { | ||
80 | unsigned int i; | ||
81 | |||
82 | for (i = PPMU_RIGHT; i < PPMU_END; i++) { | ||
83 | void __iomem *ppmu_base = data->ppmu[i].hw_base; | ||
84 | |||
85 | /* Reset the performance and cycle counters */ | ||
86 | exynos_ppmu_reset(ppmu_base); | ||
87 | |||
88 | /* Setup count registers to monitor read/write transactions */ | ||
89 | data->ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT; | ||
90 | exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3, | ||
91 | data->ppmu[i].event[PPMU_PMNCNT3]); | ||
92 | |||
93 | exynos_ppmu_start(ppmu_base); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | static void exynos5_read_ppmu(struct busfreq_data_int *data) | ||
98 | { | ||
99 | int i, j; | ||
100 | |||
101 | for (i = PPMU_RIGHT; i < PPMU_END; i++) { | ||
102 | void __iomem *ppmu_base = data->ppmu[i].hw_base; | ||
103 | |||
104 | exynos_ppmu_stop(ppmu_base); | ||
105 | |||
106 | /* Update local data from PPMU */ | ||
107 | data->ppmu[i].ccnt = __raw_readl(ppmu_base + PPMU_CCNT); | ||
108 | |||
109 | for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) { | ||
110 | if (data->ppmu[i].event[j] == 0) | ||
111 | data->ppmu[i].count[j] = 0; | ||
112 | else | ||
113 | data->ppmu[i].count[j] = | ||
114 | exynos_ppmu_read(ppmu_base, j); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | busfreq_mon_reset(data); | ||
119 | } | ||
120 | |||
121 | static int exynos5_int_setvolt(struct busfreq_data_int *data, | 78 | static int exynos5_int_setvolt(struct busfreq_data_int *data, |
122 | unsigned long volt) | 79 | unsigned long volt) |
123 | { | 80 | { |
@@ -185,59 +142,33 @@ out: | |||
185 | return err; | 142 | return err; |
186 | } | 143 | } |
187 | 144 | ||
188 | static int exynos5_get_busier_dmc(struct busfreq_data_int *data) | ||
189 | { | ||
190 | int i, j; | ||
191 | int busy = 0; | ||
192 | unsigned int temp = 0; | ||
193 | |||
194 | for (i = PPMU_RIGHT; i < PPMU_END; i++) { | ||
195 | for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) { | ||
196 | if (data->ppmu[i].count[j] > temp) { | ||
197 | temp = data->ppmu[i].count[j]; | ||
198 | busy = i; | ||
199 | } | ||
200 | } | ||
201 | } | ||
202 | |||
203 | return busy; | ||
204 | } | ||
205 | |||
206 | static int exynos5_int_get_dev_status(struct device *dev, | 145 | static int exynos5_int_get_dev_status(struct device *dev, |
207 | struct devfreq_dev_status *stat) | 146 | struct devfreq_dev_status *stat) |
208 | { | 147 | { |
209 | struct platform_device *pdev = container_of(dev, struct platform_device, | 148 | struct platform_device *pdev = container_of(dev, struct platform_device, |
210 | dev); | 149 | dev); |
211 | struct busfreq_data_int *data = platform_get_drvdata(pdev); | 150 | struct busfreq_data_int *data = platform_get_drvdata(pdev); |
151 | struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data; | ||
212 | int busier_dmc; | 152 | int busier_dmc; |
213 | 153 | ||
214 | exynos5_read_ppmu(data); | 154 | exynos_read_ppmu(ppmu_data); |
215 | busier_dmc = exynos5_get_busier_dmc(data); | 155 | busier_dmc = exynos_get_busier_ppmu(ppmu_data); |
216 | 156 | ||
217 | stat->current_frequency = data->curr_freq; | 157 | stat->current_frequency = data->curr_freq; |
218 | 158 | ||
219 | /* Number of cycles spent on memory access */ | 159 | /* Number of cycles spent on memory access */ |
220 | stat->busy_time = data->ppmu[busier_dmc].count[PPMU_PMNCNT3]; | 160 | stat->busy_time = ppmu_data->ppmu[busier_dmc].count[PPMU_PMNCNT3]; |
221 | stat->busy_time *= 100 / INT_BUS_SATURATION_RATIO; | 161 | stat->busy_time *= 100 / INT_BUS_SATURATION_RATIO; |
222 | stat->total_time = data->ppmu[busier_dmc].ccnt; | 162 | stat->total_time = ppmu_data->ppmu[busier_dmc].ccnt; |
223 | 163 | ||
224 | return 0; | 164 | return 0; |
225 | } | 165 | } |
226 | static void exynos5_int_exit(struct device *dev) | ||
227 | { | ||
228 | struct platform_device *pdev = container_of(dev, struct platform_device, | ||
229 | dev); | ||
230 | struct busfreq_data_int *data = platform_get_drvdata(pdev); | ||
231 | |||
232 | devfreq_unregister_opp_notifier(dev, data->devfreq); | ||
233 | } | ||
234 | 166 | ||
235 | static struct devfreq_dev_profile exynos5_devfreq_int_profile = { | 167 | static struct devfreq_dev_profile exynos5_devfreq_int_profile = { |
236 | .initial_freq = 160000, | 168 | .initial_freq = 160000, |
237 | .polling_ms = 100, | 169 | .polling_ms = 100, |
238 | .target = exynos5_busfreq_int_target, | 170 | .target = exynos5_busfreq_int_target, |
239 | .get_dev_status = exynos5_int_get_dev_status, | 171 | .get_dev_status = exynos5_int_get_dev_status, |
240 | .exit = exynos5_int_exit, | ||
241 | }; | 172 | }; |
242 | 173 | ||
243 | static int exynos5250_init_int_tables(struct busfreq_data_int *data) | 174 | static int exynos5250_init_int_tables(struct busfreq_data_int *data) |
@@ -315,6 +246,7 @@ unlock: | |||
315 | static int exynos5_busfreq_int_probe(struct platform_device *pdev) | 246 | static int exynos5_busfreq_int_probe(struct platform_device *pdev) |
316 | { | 247 | { |
317 | struct busfreq_data_int *data; | 248 | struct busfreq_data_int *data; |
249 | struct busfreq_ppmu_data *ppmu_data; | ||
318 | struct dev_pm_opp *opp; | 250 | struct dev_pm_opp *opp; |
319 | struct device *dev = &pdev->dev; | 251 | struct device *dev = &pdev->dev; |
320 | struct device_node *np; | 252 | struct device_node *np; |
@@ -330,16 +262,26 @@ static int exynos5_busfreq_int_probe(struct platform_device *pdev) | |||
330 | return -ENOMEM; | 262 | return -ENOMEM; |
331 | } | 263 | } |
332 | 264 | ||
265 | ppmu_data = &data->ppmu_data; | ||
266 | ppmu_data->ppmu_end = PPMU_END; | ||
267 | ppmu_data->ppmu = devm_kzalloc(dev, | ||
268 | sizeof(struct exynos_ppmu) * PPMU_END, | ||
269 | GFP_KERNEL); | ||
270 | if (!ppmu_data->ppmu) { | ||
271 | dev_err(dev, "Failed to allocate memory for exynos_ppmu\n"); | ||
272 | return -ENOMEM; | ||
273 | } | ||
274 | |||
333 | np = of_find_compatible_node(NULL, NULL, "samsung,exynos5250-ppmu"); | 275 | np = of_find_compatible_node(NULL, NULL, "samsung,exynos5250-ppmu"); |
334 | if (np == NULL) { | 276 | if (np == NULL) { |
335 | pr_err("Unable to find PPMU node\n"); | 277 | pr_err("Unable to find PPMU node\n"); |
336 | return -ENOENT; | 278 | return -ENOENT; |
337 | } | 279 | } |
338 | 280 | ||
339 | for (i = PPMU_RIGHT; i < PPMU_END; i++) { | 281 | for (i = 0; i < ppmu_data->ppmu_end; i++) { |
340 | /* map PPMU memory region */ | 282 | /* map PPMU memory region */ |
341 | data->ppmu[i].hw_base = of_iomap(np, i); | 283 | ppmu_data->ppmu[i].hw_base = of_iomap(np, i); |
342 | if (data->ppmu[i].hw_base == NULL) { | 284 | if (ppmu_data->ppmu[i].hw_base == NULL) { |
343 | dev_err(&pdev->dev, "failed to map memory region\n"); | 285 | dev_err(&pdev->dev, "failed to map memory region\n"); |
344 | return -ENOMEM; | 286 | return -ENOMEM; |
345 | } | 287 | } |
@@ -390,32 +332,29 @@ static int exynos5_busfreq_int_probe(struct platform_device *pdev) | |||
390 | 332 | ||
391 | platform_set_drvdata(pdev, data); | 333 | platform_set_drvdata(pdev, data); |
392 | 334 | ||
393 | busfreq_mon_reset(data); | 335 | busfreq_mon_reset(ppmu_data); |
394 | 336 | ||
395 | data->devfreq = devfreq_add_device(dev, &exynos5_devfreq_int_profile, | 337 | data->devfreq = devm_devfreq_add_device(dev, &exynos5_devfreq_int_profile, |
396 | "simple_ondemand", NULL); | 338 | "simple_ondemand", NULL); |
339 | if (IS_ERR(data->devfreq)) | ||
340 | return PTR_ERR(data->devfreq); | ||
397 | 341 | ||
398 | if (IS_ERR(data->devfreq)) { | 342 | err = devm_devfreq_register_opp_notifier(dev, data->devfreq); |
399 | err = PTR_ERR(data->devfreq); | 343 | if (err < 0) { |
400 | goto err_devfreq_add; | 344 | dev_err(dev, "Failed to register opp notifier\n"); |
345 | return err; | ||
401 | } | 346 | } |
402 | 347 | ||
403 | devfreq_register_opp_notifier(dev, data->devfreq); | ||
404 | |||
405 | err = register_pm_notifier(&data->pm_notifier); | 348 | err = register_pm_notifier(&data->pm_notifier); |
406 | if (err) { | 349 | if (err) { |
407 | dev_err(dev, "Failed to setup pm notifier\n"); | 350 | dev_err(dev, "Failed to setup pm notifier\n"); |
408 | goto err_devfreq_add; | 351 | return err; |
409 | } | 352 | } |
410 | 353 | ||
411 | /* TODO: Add a new QOS class for int/mif bus */ | 354 | /* TODO: Add a new QOS class for int/mif bus */ |
412 | pm_qos_add_request(&data->int_req, PM_QOS_NETWORK_THROUGHPUT, -1); | 355 | pm_qos_add_request(&data->int_req, PM_QOS_NETWORK_THROUGHPUT, -1); |
413 | 356 | ||
414 | return 0; | 357 | return 0; |
415 | |||
416 | err_devfreq_add: | ||
417 | devfreq_remove_device(data->devfreq); | ||
418 | return err; | ||
419 | } | 358 | } |
420 | 359 | ||
421 | static int exynos5_busfreq_int_remove(struct platform_device *pdev) | 360 | static int exynos5_busfreq_int_remove(struct platform_device *pdev) |
@@ -424,24 +363,27 @@ static int exynos5_busfreq_int_remove(struct platform_device *pdev) | |||
424 | 363 | ||
425 | pm_qos_remove_request(&data->int_req); | 364 | pm_qos_remove_request(&data->int_req); |
426 | unregister_pm_notifier(&data->pm_notifier); | 365 | unregister_pm_notifier(&data->pm_notifier); |
427 | devfreq_remove_device(data->devfreq); | ||
428 | 366 | ||
429 | return 0; | 367 | return 0; |
430 | } | 368 | } |
431 | 369 | ||
370 | #ifdef CONFIG_PM_SLEEP | ||
432 | static int exynos5_busfreq_int_resume(struct device *dev) | 371 | static int exynos5_busfreq_int_resume(struct device *dev) |
433 | { | 372 | { |
434 | struct platform_device *pdev = container_of(dev, struct platform_device, | 373 | struct platform_device *pdev = container_of(dev, struct platform_device, |
435 | dev); | 374 | dev); |
436 | struct busfreq_data_int *data = platform_get_drvdata(pdev); | 375 | struct busfreq_data_int *data = platform_get_drvdata(pdev); |
376 | struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data; | ||
437 | 377 | ||
438 | busfreq_mon_reset(data); | 378 | busfreq_mon_reset(ppmu_data); |
439 | return 0; | 379 | return 0; |
440 | } | 380 | } |
441 | |||
442 | static const struct dev_pm_ops exynos5_busfreq_int_pm = { | 381 | static const struct dev_pm_ops exynos5_busfreq_int_pm = { |
443 | .resume = exynos5_busfreq_int_resume, | 382 | .resume = exynos5_busfreq_int_resume, |
444 | }; | 383 | }; |
384 | #endif | ||
385 | static SIMPLE_DEV_PM_OPS(exynos5_busfreq_int_pm_ops, NULL, | ||
386 | exynos5_busfreq_int_resume); | ||
445 | 387 | ||
446 | /* platform device pointer for exynos5 devfreq device. */ | 388 | /* platform device pointer for exynos5 devfreq device. */ |
447 | static struct platform_device *exynos5_devfreq_pdev; | 389 | static struct platform_device *exynos5_devfreq_pdev; |
@@ -452,7 +394,7 @@ static struct platform_driver exynos5_busfreq_int_driver = { | |||
452 | .driver = { | 394 | .driver = { |
453 | .name = "exynos5-bus-int", | 395 | .name = "exynos5-bus-int", |
454 | .owner = THIS_MODULE, | 396 | .owner = THIS_MODULE, |
455 | .pm = &exynos5_busfreq_int_pm, | 397 | .pm = &exynos5_busfreq_int_pm_ops, |
456 | }, | 398 | }, |
457 | }; | 399 | }; |
458 | 400 | ||
diff --git a/drivers/devfreq/exynos/exynos_ppmu.c b/drivers/devfreq/exynos/exynos_ppmu.c index 85fc5ac1036a..75fcc5140ffb 100644 --- a/drivers/devfreq/exynos/exynos_ppmu.c +++ b/drivers/devfreq/exynos/exynos_ppmu.c | |||
@@ -54,3 +54,63 @@ unsigned int exynos_ppmu_read(void __iomem *ppmu_base, unsigned int ch) | |||
54 | 54 | ||
55 | return total; | 55 | return total; |
56 | } | 56 | } |
57 | |||
58 | void busfreq_mon_reset(struct busfreq_ppmu_data *ppmu_data) | ||
59 | { | ||
60 | unsigned int i; | ||
61 | |||
62 | for (i = 0; i < ppmu_data->ppmu_end; i++) { | ||
63 | void __iomem *ppmu_base = ppmu_data->ppmu[i].hw_base; | ||
64 | |||
65 | /* Reset the performance and cycle counters */ | ||
66 | exynos_ppmu_reset(ppmu_base); | ||
67 | |||
68 | /* Setup count registers to monitor read/write transactions */ | ||
69 | ppmu_data->ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT; | ||
70 | exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3, | ||
71 | ppmu_data->ppmu[i].event[PPMU_PMNCNT3]); | ||
72 | |||
73 | exynos_ppmu_start(ppmu_base); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | void exynos_read_ppmu(struct busfreq_ppmu_data *ppmu_data) | ||
78 | { | ||
79 | int i, j; | ||
80 | |||
81 | for (i = 0; i < ppmu_data->ppmu_end; i++) { | ||
82 | void __iomem *ppmu_base = ppmu_data->ppmu[i].hw_base; | ||
83 | |||
84 | exynos_ppmu_stop(ppmu_base); | ||
85 | |||
86 | /* Update local data from PPMU */ | ||
87 | ppmu_data->ppmu[i].ccnt = __raw_readl(ppmu_base + PPMU_CCNT); | ||
88 | |||
89 | for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) { | ||
90 | if (ppmu_data->ppmu[i].event[j] == 0) | ||
91 | ppmu_data->ppmu[i].count[j] = 0; | ||
92 | else | ||
93 | ppmu_data->ppmu[i].count[j] = | ||
94 | exynos_ppmu_read(ppmu_base, j); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | busfreq_mon_reset(ppmu_data); | ||
99 | } | ||
100 | |||
101 | int exynos_get_busier_ppmu(struct busfreq_ppmu_data *ppmu_data) | ||
102 | { | ||
103 | unsigned int count = 0; | ||
104 | int i, j, busy = 0; | ||
105 | |||
106 | for (i = 0; i < ppmu_data->ppmu_end; i++) { | ||
107 | for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) { | ||
108 | if (ppmu_data->ppmu[i].count[j] > count) { | ||
109 | count = ppmu_data->ppmu[i].count[j]; | ||
110 | busy = i; | ||
111 | } | ||
112 | } | ||
113 | } | ||
114 | |||
115 | return busy; | ||
116 | } | ||
diff --git a/drivers/devfreq/exynos/exynos_ppmu.h b/drivers/devfreq/exynos/exynos_ppmu.h index 7dfb221eaccd..71f17ba3563c 100644 --- a/drivers/devfreq/exynos/exynos_ppmu.h +++ b/drivers/devfreq/exynos/exynos_ppmu.h | |||
@@ -69,10 +69,18 @@ struct exynos_ppmu { | |||
69 | bool count_overflow[PPMU_PMNCNT_MAX]; | 69 | bool count_overflow[PPMU_PMNCNT_MAX]; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | struct busfreq_ppmu_data { | ||
73 | struct exynos_ppmu *ppmu; | ||
74 | int ppmu_end; | ||
75 | }; | ||
76 | |||
72 | void exynos_ppmu_reset(void __iomem *ppmu_base); | 77 | void exynos_ppmu_reset(void __iomem *ppmu_base); |
73 | void exynos_ppmu_setevent(void __iomem *ppmu_base, unsigned int ch, | 78 | void exynos_ppmu_setevent(void __iomem *ppmu_base, unsigned int ch, |
74 | unsigned int evt); | 79 | unsigned int evt); |
75 | void exynos_ppmu_start(void __iomem *ppmu_base); | 80 | void exynos_ppmu_start(void __iomem *ppmu_base); |
76 | void exynos_ppmu_stop(void __iomem *ppmu_base); | 81 | void exynos_ppmu_stop(void __iomem *ppmu_base); |
77 | unsigned int exynos_ppmu_read(void __iomem *ppmu_base, unsigned int ch); | 82 | unsigned int exynos_ppmu_read(void __iomem *ppmu_base, unsigned int ch); |
83 | void busfreq_mon_reset(struct busfreq_ppmu_data *ppmu_data); | ||
84 | void exynos_read_ppmu(struct busfreq_ppmu_data *ppmu_data); | ||
85 | int exynos_get_busier_ppmu(struct busfreq_ppmu_data *ppmu_data); | ||
78 | #endif /* __DEVFREQ_EXYNOS_PPMU_H */ | 86 | #endif /* __DEVFREQ_EXYNOS_PPMU_H */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 630f6e84fc01..2c1e4aad7da3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c | |||
@@ -31,7 +31,6 @@ | |||
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include <linux/backlight.h> | 33 | #include <linux/backlight.h> |
34 | #include <linux/acpi.h> | ||
35 | 34 | ||
36 | #include "nouveau_drm.h" | 35 | #include "nouveau_drm.h" |
37 | #include "nouveau_reg.h" | 36 | #include "nouveau_reg.h" |
@@ -222,14 +221,6 @@ nouveau_backlight_init(struct drm_device *dev) | |||
222 | struct nouveau_device *device = nv_device(drm->device); | 221 | struct nouveau_device *device = nv_device(drm->device); |
223 | struct drm_connector *connector; | 222 | struct drm_connector *connector; |
224 | 223 | ||
225 | #ifdef CONFIG_ACPI | ||
226 | if (acpi_video_backlight_support()) { | ||
227 | NV_INFO(drm, "ACPI backlight interface available, " | ||
228 | "not registering our own\n"); | ||
229 | return 0; | ||
230 | } | ||
231 | #endif | ||
232 | |||
233 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 224 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
234 | if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && | 225 | if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && |
235 | connector->connector_type != DRM_MODE_CONNECTOR_eDP) | 226 | connector->connector_type != DRM_MODE_CONNECTOR_eDP) |
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 7694e0700d34..b11fdd63eecd 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -1734,18 +1734,17 @@ static struct cpufreq_frequency_table db8500_cpufreq_table[] = { | |||
1734 | 1734 | ||
1735 | static long round_armss_rate(unsigned long rate) | 1735 | static long round_armss_rate(unsigned long rate) |
1736 | { | 1736 | { |
1737 | struct cpufreq_frequency_table *pos; | ||
1737 | long freq = 0; | 1738 | long freq = 0; |
1738 | int i = 0; | ||
1739 | 1739 | ||
1740 | /* cpufreq table frequencies is in KHz. */ | 1740 | /* cpufreq table frequencies is in KHz. */ |
1741 | rate = rate / 1000; | 1741 | rate = rate / 1000; |
1742 | 1742 | ||
1743 | /* Find the corresponding arm opp from the cpufreq table. */ | 1743 | /* Find the corresponding arm opp from the cpufreq table. */ |
1744 | while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) { | 1744 | cpufreq_for_each_entry(pos, db8500_cpufreq_table) { |
1745 | freq = db8500_cpufreq_table[i].frequency; | 1745 | freq = pos->frequency; |
1746 | if (freq == rate) | 1746 | if (freq == rate) |
1747 | break; | 1747 | break; |
1748 | i++; | ||
1749 | } | 1748 | } |
1750 | 1749 | ||
1751 | /* Return the last valid value, even if a match was not found. */ | 1750 | /* Return the last valid value, even if a match was not found. */ |
@@ -1886,23 +1885,21 @@ static void set_clock_rate(u8 clock, unsigned long rate) | |||
1886 | 1885 | ||
1887 | static int set_armss_rate(unsigned long rate) | 1886 | static int set_armss_rate(unsigned long rate) |
1888 | { | 1887 | { |
1889 | int i = 0; | 1888 | struct cpufreq_frequency_table *pos; |
1890 | 1889 | ||
1891 | /* cpufreq table frequencies is in KHz. */ | 1890 | /* cpufreq table frequencies is in KHz. */ |
1892 | rate = rate / 1000; | 1891 | rate = rate / 1000; |
1893 | 1892 | ||
1894 | /* Find the corresponding arm opp from the cpufreq table. */ | 1893 | /* Find the corresponding arm opp from the cpufreq table. */ |
1895 | while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) { | 1894 | cpufreq_for_each_entry(pos, db8500_cpufreq_table) |
1896 | if (db8500_cpufreq_table[i].frequency == rate) | 1895 | if (pos->frequency == rate) |
1897 | break; | 1896 | break; |
1898 | i++; | ||
1899 | } | ||
1900 | 1897 | ||
1901 | if (db8500_cpufreq_table[i].frequency != rate) | 1898 | if (pos->frequency != rate) |
1902 | return -EINVAL; | 1899 | return -EINVAL; |
1903 | 1900 | ||
1904 | /* Set the new arm opp. */ | 1901 | /* Set the new arm opp. */ |
1905 | return db8500_prcmu_set_arm_opp(db8500_cpufreq_table[i].driver_data); | 1902 | return db8500_prcmu_set_arm_opp(pos->driver_data); |
1906 | } | 1903 | } |
1907 | 1904 | ||
1908 | static int set_plldsi_rate(unsigned long rate) | 1905 | static int set_plldsi_rate(unsigned long rate) |
diff --git a/drivers/net/irda/sh_sir.c b/drivers/net/irda/sh_sir.c index cadf52e22464..e3fe9a286136 100644 --- a/drivers/net/irda/sh_sir.c +++ b/drivers/net/irda/sh_sir.c | |||
@@ -217,21 +217,17 @@ crc_init_out: | |||
217 | static u32 sh_sir_find_sclk(struct clk *irda_clk) | 217 | static u32 sh_sir_find_sclk(struct clk *irda_clk) |
218 | { | 218 | { |
219 | struct cpufreq_frequency_table *freq_table = irda_clk->freq_table; | 219 | struct cpufreq_frequency_table *freq_table = irda_clk->freq_table; |
220 | struct cpufreq_frequency_table *pos; | ||
220 | struct clk *pclk = clk_get(NULL, "peripheral_clk"); | 221 | struct clk *pclk = clk_get(NULL, "peripheral_clk"); |
221 | u32 limit, min = 0xffffffff, tmp; | 222 | u32 limit, min = 0xffffffff, tmp; |
222 | int i, index = 0; | 223 | int index = 0; |
223 | 224 | ||
224 | limit = clk_get_rate(pclk); | 225 | limit = clk_get_rate(pclk); |
225 | clk_put(pclk); | 226 | clk_put(pclk); |
226 | 227 | ||
227 | /* IrDA can not set over peripheral_clk */ | 228 | /* IrDA can not set over peripheral_clk */ |
228 | for (i = 0; | 229 | cpufreq_for_each_valid_entry(pos, freq_table) { |
229 | freq_table[i].frequency != CPUFREQ_TABLE_END; | 230 | u32 freq = pos->frequency; |
230 | i++) { | ||
231 | u32 freq = freq_table[i].frequency; | ||
232 | |||
233 | if (freq == CPUFREQ_ENTRY_INVALID) | ||
234 | continue; | ||
235 | 231 | ||
236 | /* IrDA should not over peripheral_clk */ | 232 | /* IrDA should not over peripheral_clk */ |
237 | if (freq > limit) | 233 | if (freq > limit) |
@@ -240,7 +236,7 @@ static u32 sh_sir_find_sclk(struct clk *irda_clk) | |||
240 | tmp = freq % SCLK_BASE; | 236 | tmp = freq % SCLK_BASE; |
241 | if (tmp < min) { | 237 | if (tmp < min) { |
242 | min = tmp; | 238 | min = tmp; |
243 | index = i; | 239 | index = pos - freq_table; |
244 | } | 240 | } |
245 | } | 241 | } |
246 | 242 | ||
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index c91f69b39db4..bbf78b2d6d93 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -570,6 +570,14 @@ static const struct dmi_system_id video_vendor_dmi_table[] = { | |||
570 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5750"), | 570 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5750"), |
571 | }, | 571 | }, |
572 | }, | 572 | }, |
573 | { | ||
574 | .callback = video_set_backlight_video_vendor, | ||
575 | .ident = "Acer Aspire 5741", | ||
576 | .matches = { | ||
577 | DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), | ||
578 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5741"), | ||
579 | }, | ||
580 | }, | ||
573 | {} | 581 | {} |
574 | }; | 582 | }; |
575 | 583 | ||
@@ -2228,7 +2236,7 @@ static int __init acer_wmi_init(void) | |||
2228 | pr_info("Brightness must be controlled by acpi video driver\n"); | 2236 | pr_info("Brightness must be controlled by acpi video driver\n"); |
2229 | } else { | 2237 | } else { |
2230 | pr_info("Disabling ACPI video driver\n"); | 2238 | pr_info("Disabling ACPI video driver\n"); |
2231 | acpi_video_unregister(); | 2239 | acpi_video_unregister_backlight(); |
2232 | } | 2240 | } |
2233 | 2241 | ||
2234 | if (wmi_has_guid(WMID_GUID3)) { | 2242 | if (wmi_has_guid(WMID_GUID3)) { |
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index c31aa07b3ba5..b81448b2c75d 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -30,26 +30,6 @@ | |||
30 | 30 | ||
31 | static int num; | 31 | static int num; |
32 | 32 | ||
33 | /* We need only to blacklist devices that have already an acpi driver that | ||
34 | * can't use pnp layer. We don't need to blacklist device that are directly | ||
35 | * used by the kernel (PCI root, ...), as it is harmless and there were | ||
36 | * already present in pnpbios. But there is an exception for devices that | ||
37 | * have irqs (PIC, Timer) because we call acpi_register_gsi. | ||
38 | * Finally, only devices that have a CRS method need to be in this list. | ||
39 | */ | ||
40 | static struct acpi_device_id excluded_id_list[] __initdata = { | ||
41 | {"PNP0C09", 0}, /* EC */ | ||
42 | {"PNP0C0F", 0}, /* Link device */ | ||
43 | {"PNP0000", 0}, /* PIC */ | ||
44 | {"PNP0100", 0}, /* Timer */ | ||
45 | {"", 0}, | ||
46 | }; | ||
47 | |||
48 | static inline int __init is_exclusive_device(struct acpi_device *dev) | ||
49 | { | ||
50 | return (!acpi_match_device_ids(dev, excluded_id_list)); | ||
51 | } | ||
52 | |||
53 | /* | 33 | /* |
54 | * Compatible Device IDs | 34 | * Compatible Device IDs |
55 | */ | 35 | */ |
@@ -266,7 +246,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device) | |||
266 | if (!pnpid) | 246 | if (!pnpid) |
267 | return 0; | 247 | return 0; |
268 | 248 | ||
269 | if (is_exclusive_device(device) || !device->status.present) | 249 | if (!device->status.present) |
270 | return 0; | 250 | return 0; |
271 | 251 | ||
272 | dev = pnp_alloc_dev(&pnpacpi_protocol, num, pnpid); | 252 | dev = pnp_alloc_dev(&pnpacpi_protocol, num, pnpid); |
@@ -326,10 +306,10 @@ static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, | |||
326 | { | 306 | { |
327 | struct acpi_device *device; | 307 | struct acpi_device *device; |
328 | 308 | ||
329 | if (!acpi_bus_get_device(handle, &device)) | 309 | if (acpi_bus_get_device(handle, &device)) |
330 | pnpacpi_add_device(device); | ||
331 | else | ||
332 | return AE_CTRL_DEPTH; | 310 | return AE_CTRL_DEPTH; |
311 | if (acpi_is_pnp_device(device)) | ||
312 | pnpacpi_add_device(device); | ||
333 | return AE_OK; | 313 | return AE_OK; |
334 | } | 314 | } |
335 | 315 | ||
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 01712cbfd92e..782e82289571 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c | |||
@@ -360,7 +360,7 @@ int pnp_check_irq(struct pnp_dev *dev, struct resource *res) | |||
360 | return 1; | 360 | return 1; |
361 | 361 | ||
362 | /* check if the resource is valid */ | 362 | /* check if the resource is valid */ |
363 | if (*irq < 0 || *irq > 15) | 363 | if (*irq > 15) |
364 | return 0; | 364 | return 0; |
365 | 365 | ||
366 | /* check if the resource is reserved */ | 366 | /* check if the resource is reserved */ |
@@ -424,7 +424,7 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res) | |||
424 | return 1; | 424 | return 1; |
425 | 425 | ||
426 | /* check if the resource is valid */ | 426 | /* check if the resource is valid */ |
427 | if (*dma < 0 || *dma == 4 || *dma > 7) | 427 | if (*dma == 4 || *dma > 7) |
428 | return 0; | 428 | return 0; |
429 | 429 | ||
430 | /* check if the resource is reserved */ | 430 | /* check if the resource is reserved */ |
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index 26606641fe44..5a5a24e7d43c 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c | |||
@@ -537,7 +537,7 @@ static void psy_unregister_cooler(struct power_supply *psy) | |||
537 | } | 537 | } |
538 | #endif | 538 | #endif |
539 | 539 | ||
540 | int power_supply_register(struct device *parent, struct power_supply *psy) | 540 | int __power_supply_register(struct device *parent, struct power_supply *psy, bool ws) |
541 | { | 541 | { |
542 | struct device *dev; | 542 | struct device *dev; |
543 | int rc; | 543 | int rc; |
@@ -568,7 +568,7 @@ int power_supply_register(struct device *parent, struct power_supply *psy) | |||
568 | } | 568 | } |
569 | 569 | ||
570 | spin_lock_init(&psy->changed_lock); | 570 | spin_lock_init(&psy->changed_lock); |
571 | rc = device_init_wakeup(dev, true); | 571 | rc = device_init_wakeup(dev, ws); |
572 | if (rc) | 572 | if (rc) |
573 | goto wakeup_init_failed; | 573 | goto wakeup_init_failed; |
574 | 574 | ||
@@ -606,8 +606,19 @@ dev_set_name_failed: | |||
606 | success: | 606 | success: |
607 | return rc; | 607 | return rc; |
608 | } | 608 | } |
609 | |||
610 | int power_supply_register(struct device *parent, struct power_supply *psy) | ||
611 | { | ||
612 | return __power_supply_register(parent, psy, true); | ||
613 | } | ||
609 | EXPORT_SYMBOL_GPL(power_supply_register); | 614 | EXPORT_SYMBOL_GPL(power_supply_register); |
610 | 615 | ||
616 | int power_supply_register_no_ws(struct device *parent, struct power_supply *psy) | ||
617 | { | ||
618 | return __power_supply_register(parent, psy, false); | ||
619 | } | ||
620 | EXPORT_SYMBOL_GPL(power_supply_register_no_ws); | ||
621 | |||
611 | void power_supply_unregister(struct power_supply *psy) | 622 | void power_supply_unregister(struct power_supply *psy) |
612 | { | 623 | { |
613 | cancel_work_sync(&psy->changed_work); | 624 | cancel_work_sync(&psy->changed_work); |
diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index d9a0770b6c73..b1cda6ffdbcc 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c | |||
@@ -951,7 +951,9 @@ static const struct x86_cpu_id rapl_ids[] = { | |||
951 | { X86_VENDOR_INTEL, 6, 0x2d},/* Sandy Bridge EP */ | 951 | { X86_VENDOR_INTEL, 6, 0x2d},/* Sandy Bridge EP */ |
952 | { X86_VENDOR_INTEL, 6, 0x37},/* Valleyview */ | 952 | { X86_VENDOR_INTEL, 6, 0x37},/* Valleyview */ |
953 | { X86_VENDOR_INTEL, 6, 0x3a},/* Ivy Bridge */ | 953 | { X86_VENDOR_INTEL, 6, 0x3a},/* Ivy Bridge */ |
954 | { X86_VENDOR_INTEL, 6, 0x45},/* Haswell */ | 954 | { X86_VENDOR_INTEL, 6, 0x3c},/* Haswell */ |
955 | { X86_VENDOR_INTEL, 6, 0x3d},/* Broadwell */ | ||
956 | { X86_VENDOR_INTEL, 6, 0x45},/* Haswell ULT */ | ||
955 | /* TODO: Add more CPU IDs after testing */ | 957 | /* TODO: Add more CPU IDs after testing */ |
956 | {} | 958 | {} |
957 | }; | 959 | }; |
@@ -1124,8 +1126,7 @@ err_cleanup_package: | |||
1124 | static int rapl_check_domain(int cpu, int domain) | 1126 | static int rapl_check_domain(int cpu, int domain) |
1125 | { | 1127 | { |
1126 | unsigned msr; | 1128 | unsigned msr; |
1127 | u64 val1, val2 = 0; | 1129 | u64 val = 0; |
1128 | int retry = 0; | ||
1129 | 1130 | ||
1130 | switch (domain) { | 1131 | switch (domain) { |
1131 | case RAPL_DOMAIN_PACKAGE: | 1132 | case RAPL_DOMAIN_PACKAGE: |
@@ -1144,26 +1145,13 @@ static int rapl_check_domain(int cpu, int domain) | |||
1144 | pr_err("invalid domain id %d\n", domain); | 1145 | pr_err("invalid domain id %d\n", domain); |
1145 | return -EINVAL; | 1146 | return -EINVAL; |
1146 | } | 1147 | } |
1147 | if (rdmsrl_safe_on_cpu(cpu, msr, &val1)) | 1148 | /* make sure domain counters are available and contains non-zero |
1148 | return -ENODEV; | 1149 | * values, otherwise skip it. |
1149 | |||
1150 | /* PP1/uncore/graphics domain may not be active at the time of | ||
1151 | * driver loading. So skip further checks. | ||
1152 | */ | 1150 | */ |
1153 | if (domain == RAPL_DOMAIN_PP1) | 1151 | if (rdmsrl_safe_on_cpu(cpu, msr, &val) || !val) |
1154 | return 0; | 1152 | return -ENODEV; |
1155 | /* energy counters roll slowly on some domains */ | ||
1156 | while (++retry < 10) { | ||
1157 | usleep_range(10000, 15000); | ||
1158 | rdmsrl_safe_on_cpu(cpu, msr, &val2); | ||
1159 | if ((val1 & ENERGY_STATUS_MASK) != (val2 & ENERGY_STATUS_MASK)) | ||
1160 | return 0; | ||
1161 | } | ||
1162 | /* if energy counter does not change, report as bad domain */ | ||
1163 | pr_info("domain %s energy ctr %llu:%llu not working, skip\n", | ||
1164 | rapl_domain_names[domain], val1, val2); | ||
1165 | 1153 | ||
1166 | return -ENODEV; | 1154 | return 0; |
1167 | } | 1155 | } |
1168 | 1156 | ||
1169 | /* Detect active and valid domains for the given CPU, caller must | 1157 | /* Detect active and valid domains for the given CPU, caller must |
@@ -1180,6 +1168,9 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu) | |||
1180 | /* use physical package id to read counters */ | 1168 | /* use physical package id to read counters */ |
1181 | if (!rapl_check_domain(cpu, i)) | 1169 | if (!rapl_check_domain(cpu, i)) |
1182 | rp->domain_map |= 1 << i; | 1170 | rp->domain_map |= 1 << i; |
1171 | else | ||
1172 | pr_warn("RAPL domain %s detection failed\n", | ||
1173 | rapl_domain_names[i]); | ||
1183 | } | 1174 | } |
1184 | rp->nr_domains = bitmap_weight(&rp->domain_map, RAPL_DOMAIN_MAX); | 1175 | rp->nr_domains = bitmap_weight(&rp->domain_map, RAPL_DOMAIN_MAX); |
1185 | if (!rp->nr_domains) { | 1176 | if (!rp->nr_domains) { |
diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c index 74727851820d..be56b22ca941 100644 --- a/drivers/sh/clk/core.c +++ b/drivers/sh/clk/core.c | |||
@@ -196,17 +196,11 @@ int clk_rate_table_find(struct clk *clk, | |||
196 | struct cpufreq_frequency_table *freq_table, | 196 | struct cpufreq_frequency_table *freq_table, |
197 | unsigned long rate) | 197 | unsigned long rate) |
198 | { | 198 | { |
199 | int i; | 199 | struct cpufreq_frequency_table *pos; |
200 | |||
201 | for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { | ||
202 | unsigned long freq = freq_table[i].frequency; | ||
203 | 200 | ||
204 | if (freq == CPUFREQ_ENTRY_INVALID) | 201 | cpufreq_for_each_valid_entry(pos, freq_table) |
205 | continue; | 202 | if (pos->frequency == rate) |
206 | 203 | return pos - freq_table; | |
207 | if (freq == rate) | ||
208 | return i; | ||
209 | } | ||
210 | 204 | ||
211 | return -ENOENT; | 205 | return -ENOENT; |
212 | } | 206 | } |
@@ -575,11 +569,7 @@ long clk_round_parent(struct clk *clk, unsigned long target, | |||
575 | return abs(target - *best_freq); | 569 | return abs(target - *best_freq); |
576 | } | 570 | } |
577 | 571 | ||
578 | for (freq = parent->freq_table; freq->frequency != CPUFREQ_TABLE_END; | 572 | cpufreq_for_each_valid_entry(freq, parent->freq_table) { |
579 | freq++) { | ||
580 | if (freq->frequency == CPUFREQ_ENTRY_INVALID) | ||
581 | continue; | ||
582 | |||
583 | if (unlikely(freq->frequency / target <= div_min - 1)) { | 573 | if (unlikely(freq->frequency / target <= div_min - 1)) { |
584 | unsigned long freq_max; | 574 | unsigned long freq_max; |
585 | 575 | ||
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 4246262c4bd2..84a75f89bf74 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c | |||
@@ -144,11 +144,11 @@ static int get_property(unsigned int cpu, unsigned long input, | |||
144 | unsigned int *output, | 144 | unsigned int *output, |
145 | enum cpufreq_cooling_property property) | 145 | enum cpufreq_cooling_property property) |
146 | { | 146 | { |
147 | int i, j; | 147 | int i; |
148 | unsigned long max_level = 0, level = 0; | 148 | unsigned long max_level = 0, level = 0; |
149 | unsigned int freq = CPUFREQ_ENTRY_INVALID; | 149 | unsigned int freq = CPUFREQ_ENTRY_INVALID; |
150 | int descend = -1; | 150 | int descend = -1; |
151 | struct cpufreq_frequency_table *table = | 151 | struct cpufreq_frequency_table *pos, *table = |
152 | cpufreq_frequency_get_table(cpu); | 152 | cpufreq_frequency_get_table(cpu); |
153 | 153 | ||
154 | if (!output) | 154 | if (!output) |
@@ -157,20 +157,16 @@ static int get_property(unsigned int cpu, unsigned long input, | |||
157 | if (!table) | 157 | if (!table) |
158 | return -EINVAL; | 158 | return -EINVAL; |
159 | 159 | ||
160 | for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { | 160 | cpufreq_for_each_valid_entry(pos, table) { |
161 | /* ignore invalid entries */ | ||
162 | if (table[i].frequency == CPUFREQ_ENTRY_INVALID) | ||
163 | continue; | ||
164 | |||
165 | /* ignore duplicate entry */ | 161 | /* ignore duplicate entry */ |
166 | if (freq == table[i].frequency) | 162 | if (freq == pos->frequency) |
167 | continue; | 163 | continue; |
168 | 164 | ||
169 | /* get the frequency order */ | 165 | /* get the frequency order */ |
170 | if (freq != CPUFREQ_ENTRY_INVALID && descend == -1) | 166 | if (freq != CPUFREQ_ENTRY_INVALID && descend == -1) |
171 | descend = !!(freq > table[i].frequency); | 167 | descend = freq > pos->frequency; |
172 | 168 | ||
173 | freq = table[i].frequency; | 169 | freq = pos->frequency; |
174 | max_level++; | 170 | max_level++; |
175 | } | 171 | } |
176 | 172 | ||
@@ -190,29 +186,26 @@ static int get_property(unsigned int cpu, unsigned long input, | |||
190 | if (property == GET_FREQ) | 186 | if (property == GET_FREQ) |
191 | level = descend ? input : (max_level - input); | 187 | level = descend ? input : (max_level - input); |
192 | 188 | ||
193 | for (i = 0, j = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { | 189 | i = 0; |
194 | /* ignore invalid entry */ | 190 | cpufreq_for_each_valid_entry(pos, table) { |
195 | if (table[i].frequency == CPUFREQ_ENTRY_INVALID) | ||
196 | continue; | ||
197 | |||
198 | /* ignore duplicate entry */ | 191 | /* ignore duplicate entry */ |
199 | if (freq == table[i].frequency) | 192 | if (freq == pos->frequency) |
200 | continue; | 193 | continue; |
201 | 194 | ||
202 | /* now we have a valid frequency entry */ | 195 | /* now we have a valid frequency entry */ |
203 | freq = table[i].frequency; | 196 | freq = pos->frequency; |
204 | 197 | ||
205 | if (property == GET_LEVEL && (unsigned int)input == freq) { | 198 | if (property == GET_LEVEL && (unsigned int)input == freq) { |
206 | /* get level by frequency */ | 199 | /* get level by frequency */ |
207 | *output = descend ? j : (max_level - j); | 200 | *output = descend ? i : (max_level - i); |
208 | return 0; | 201 | return 0; |
209 | } | 202 | } |
210 | if (property == GET_FREQ && level == j) { | 203 | if (property == GET_FREQ && level == i) { |
211 | /* get frequency by level */ | 204 | /* get frequency by level */ |
212 | *output = freq; | 205 | *output = freq; |
213 | return 0; | 206 | return 0; |
214 | } | 207 | } |
215 | j++; | 208 | i++; |
216 | } | 209 | } |
217 | 210 | ||
218 | return -EINVAL; | 211 | return -EINVAL; |
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index bd2172c2d650..428089009cd5 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | static struct list_head backlight_dev_list; | 24 | static struct list_head backlight_dev_list; |
25 | static struct mutex backlight_dev_list_mutex; | 25 | static struct mutex backlight_dev_list_mutex; |
26 | static struct blocking_notifier_head backlight_notifier; | ||
26 | 27 | ||
27 | static const char *const backlight_types[] = { | 28 | static const char *const backlight_types[] = { |
28 | [BACKLIGHT_RAW] = "raw", | 29 | [BACKLIGHT_RAW] = "raw", |
@@ -370,6 +371,9 @@ struct backlight_device *backlight_device_register(const char *name, | |||
370 | list_add(&new_bd->entry, &backlight_dev_list); | 371 | list_add(&new_bd->entry, &backlight_dev_list); |
371 | mutex_unlock(&backlight_dev_list_mutex); | 372 | mutex_unlock(&backlight_dev_list_mutex); |
372 | 373 | ||
374 | blocking_notifier_call_chain(&backlight_notifier, | ||
375 | BACKLIGHT_REGISTERED, new_bd); | ||
376 | |||
373 | return new_bd; | 377 | return new_bd; |
374 | } | 378 | } |
375 | EXPORT_SYMBOL(backlight_device_register); | 379 | EXPORT_SYMBOL(backlight_device_register); |
@@ -413,6 +417,10 @@ void backlight_device_unregister(struct backlight_device *bd) | |||
413 | pmac_backlight = NULL; | 417 | pmac_backlight = NULL; |
414 | mutex_unlock(&pmac_backlight_mutex); | 418 | mutex_unlock(&pmac_backlight_mutex); |
415 | #endif | 419 | #endif |
420 | |||
421 | blocking_notifier_call_chain(&backlight_notifier, | ||
422 | BACKLIGHT_UNREGISTERED, bd); | ||
423 | |||
416 | mutex_lock(&bd->ops_lock); | 424 | mutex_lock(&bd->ops_lock); |
417 | bd->ops = NULL; | 425 | bd->ops = NULL; |
418 | mutex_unlock(&bd->ops_lock); | 426 | mutex_unlock(&bd->ops_lock); |
@@ -438,6 +446,36 @@ static int devm_backlight_device_match(struct device *dev, void *res, | |||
438 | } | 446 | } |
439 | 447 | ||
440 | /** | 448 | /** |
449 | * backlight_register_notifier - get notified of backlight (un)registration | ||
450 | * @nb: notifier block with the notifier to call on backlight (un)registration | ||
451 | * | ||
452 | * @return 0 on success, otherwise a negative error code | ||
453 | * | ||
454 | * Register a notifier to get notified when backlight devices get registered | ||
455 | * or unregistered. | ||
456 | */ | ||
457 | int backlight_register_notifier(struct notifier_block *nb) | ||
458 | { | ||
459 | return blocking_notifier_chain_register(&backlight_notifier, nb); | ||
460 | } | ||
461 | EXPORT_SYMBOL(backlight_register_notifier); | ||
462 | |||
463 | /** | ||
464 | * backlight_unregister_notifier - unregister a backlight notifier | ||
465 | * @nb: notifier block to unregister | ||
466 | * | ||
467 | * @return 0 on success, otherwise a negative error code | ||
468 | * | ||
469 | * Register a notifier to get notified when backlight devices get registered | ||
470 | * or unregistered. | ||
471 | */ | ||
472 | int backlight_unregister_notifier(struct notifier_block *nb) | ||
473 | { | ||
474 | return blocking_notifier_chain_unregister(&backlight_notifier, nb); | ||
475 | } | ||
476 | EXPORT_SYMBOL(backlight_unregister_notifier); | ||
477 | |||
478 | /** | ||
441 | * devm_backlight_device_register - resource managed backlight_device_register() | 479 | * devm_backlight_device_register - resource managed backlight_device_register() |
442 | * @dev: the device to register | 480 | * @dev: the device to register |
443 | * @name: the name of the device | 481 | * @name: the name of the device |
@@ -544,6 +582,8 @@ static int __init backlight_class_init(void) | |||
544 | backlight_class->pm = &backlight_class_dev_pm_ops; | 582 | backlight_class->pm = &backlight_class_dev_pm_ops; |
545 | INIT_LIST_HEAD(&backlight_dev_list); | 583 | INIT_LIST_HEAD(&backlight_dev_list); |
546 | mutex_init(&backlight_dev_list_mutex); | 584 | mutex_init(&backlight_dev_list_mutex); |
585 | BLOCKING_INIT_NOTIFIER_HEAD(&backlight_notifier); | ||
586 | |||
547 | return 0; | 587 | return 0; |
548 | } | 588 | } |
549 | 589 | ||