diff options
-rw-r--r-- | arch/powerpc/include/asm/imc-pmu.h | 6 | ||||
-rw-r--r-- | arch/powerpc/kernel/dt_cpu_ftrs.c | 4 | ||||
-rw-r--r-- | arch/powerpc/lib/code-patching.c | 6 | ||||
-rw-r--r-- | arch/powerpc/mm/slice.c | 34 | ||||
-rw-r--r-- | arch/powerpc/perf/imc-pmu.c | 27 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-imc.c | 22 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/vas.c | 1 |
7 files changed, 66 insertions, 34 deletions
diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h index 7f74c282710f..fad0e6ff460f 100644 --- a/arch/powerpc/include/asm/imc-pmu.h +++ b/arch/powerpc/include/asm/imc-pmu.h | |||
@@ -21,11 +21,6 @@ | |||
21 | #include <asm/opal.h> | 21 | #include <asm/opal.h> |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * For static allocation of some of the structures. | ||
25 | */ | ||
26 | #define IMC_MAX_PMUS 32 | ||
27 | |||
28 | /* | ||
29 | * Compatibility macros for IMC devices | 24 | * Compatibility macros for IMC devices |
30 | */ | 25 | */ |
31 | #define IMC_DTB_COMPAT "ibm,opal-in-memory-counters" | 26 | #define IMC_DTB_COMPAT "ibm,opal-in-memory-counters" |
@@ -125,4 +120,5 @@ enum { | |||
125 | extern int init_imc_pmu(struct device_node *parent, | 120 | extern int init_imc_pmu(struct device_node *parent, |
126 | struct imc_pmu *pmu_ptr, int pmu_id); | 121 | struct imc_pmu *pmu_ptr, int pmu_id); |
127 | extern void thread_imc_disable(void); | 122 | extern void thread_imc_disable(void); |
123 | extern int get_max_nest_dev(void); | ||
128 | #endif /* __ASM_POWERPC_IMC_PMU_H */ | 124 | #endif /* __ASM_POWERPC_IMC_PMU_H */ |
diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c index 602e0fde19b4..8bdc2f96c5d6 100644 --- a/arch/powerpc/kernel/dt_cpu_ftrs.c +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c | |||
@@ -735,8 +735,8 @@ static __init void cpufeatures_cpu_quirks(void) | |||
735 | */ | 735 | */ |
736 | if ((version & 0xffffff00) == 0x004e0100) | 736 | if ((version & 0xffffff00) == 0x004e0100) |
737 | cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD1; | 737 | cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD1; |
738 | else if ((version & 0xffffefff) == 0x004e0200) | 738 | else if ((version & 0xffffefff) == 0x004e0201) |
739 | cur_cpu_spec->cpu_features &= ~CPU_FTR_POWER9_DD2_1; | 739 | cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1; |
740 | } | 740 | } |
741 | 741 | ||
742 | static void __init cpufeatures_setup_finished(void) | 742 | static void __init cpufeatures_setup_finished(void) |
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index c9de03e0c1f1..d469224c4ada 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/tlbflush.h> | 21 | #include <asm/tlbflush.h> |
22 | #include <asm/page.h> | 22 | #include <asm/page.h> |
23 | #include <asm/code-patching.h> | 23 | #include <asm/code-patching.h> |
24 | #include <asm/setup.h> | ||
24 | 25 | ||
25 | static int __patch_instruction(unsigned int *addr, unsigned int instr) | 26 | static int __patch_instruction(unsigned int *addr, unsigned int instr) |
26 | { | 27 | { |
@@ -146,11 +147,8 @@ int patch_instruction(unsigned int *addr, unsigned int instr) | |||
146 | * During early early boot patch_instruction is called | 147 | * During early early boot patch_instruction is called |
147 | * when text_poke_area is not ready, but we still need | 148 | * when text_poke_area is not ready, but we still need |
148 | * to allow patching. We just do the plain old patching | 149 | * to allow patching. We just do the plain old patching |
149 | * We use slab_is_available and per cpu read * via this_cpu_read | ||
150 | * of text_poke_area. Per-CPU areas might not be up early | ||
151 | * this can create problems with just using this_cpu_read() | ||
152 | */ | 150 | */ |
153 | if (!slab_is_available() || !this_cpu_read(text_poke_area)) | 151 | if (!this_cpu_read(*PTRRELOC(&text_poke_area))) |
154 | return __patch_instruction(addr, instr); | 152 | return __patch_instruction(addr, instr); |
155 | 153 | ||
156 | local_irq_save(flags); | 154 | local_irq_save(flags); |
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c index 564fff06f5c1..23ec2c5e3b78 100644 --- a/arch/powerpc/mm/slice.c +++ b/arch/powerpc/mm/slice.c | |||
@@ -122,7 +122,8 @@ static int slice_high_has_vma(struct mm_struct *mm, unsigned long slice) | |||
122 | return !slice_area_is_free(mm, start, end - start); | 122 | return !slice_area_is_free(mm, start, end - start); |
123 | } | 123 | } |
124 | 124 | ||
125 | static void slice_mask_for_free(struct mm_struct *mm, struct slice_mask *ret) | 125 | static void slice_mask_for_free(struct mm_struct *mm, struct slice_mask *ret, |
126 | unsigned long high_limit) | ||
126 | { | 127 | { |
127 | unsigned long i; | 128 | unsigned long i; |
128 | 129 | ||
@@ -133,15 +134,16 @@ static void slice_mask_for_free(struct mm_struct *mm, struct slice_mask *ret) | |||
133 | if (!slice_low_has_vma(mm, i)) | 134 | if (!slice_low_has_vma(mm, i)) |
134 | ret->low_slices |= 1u << i; | 135 | ret->low_slices |= 1u << i; |
135 | 136 | ||
136 | if (mm->context.slb_addr_limit <= SLICE_LOW_TOP) | 137 | if (high_limit <= SLICE_LOW_TOP) |
137 | return; | 138 | return; |
138 | 139 | ||
139 | for (i = 0; i < GET_HIGH_SLICE_INDEX(mm->context.slb_addr_limit); i++) | 140 | for (i = 0; i < GET_HIGH_SLICE_INDEX(high_limit); i++) |
140 | if (!slice_high_has_vma(mm, i)) | 141 | if (!slice_high_has_vma(mm, i)) |
141 | __set_bit(i, ret->high_slices); | 142 | __set_bit(i, ret->high_slices); |
142 | } | 143 | } |
143 | 144 | ||
144 | static void slice_mask_for_size(struct mm_struct *mm, int psize, struct slice_mask *ret) | 145 | static void slice_mask_for_size(struct mm_struct *mm, int psize, struct slice_mask *ret, |
146 | unsigned long high_limit) | ||
145 | { | 147 | { |
146 | unsigned char *hpsizes; | 148 | unsigned char *hpsizes; |
147 | int index, mask_index; | 149 | int index, mask_index; |
@@ -156,8 +158,11 @@ static void slice_mask_for_size(struct mm_struct *mm, int psize, struct slice_ma | |||
156 | if (((lpsizes >> (i * 4)) & 0xf) == psize) | 158 | if (((lpsizes >> (i * 4)) & 0xf) == psize) |
157 | ret->low_slices |= 1u << i; | 159 | ret->low_slices |= 1u << i; |
158 | 160 | ||
161 | if (high_limit <= SLICE_LOW_TOP) | ||
162 | return; | ||
163 | |||
159 | hpsizes = mm->context.high_slices_psize; | 164 | hpsizes = mm->context.high_slices_psize; |
160 | for (i = 0; i < GET_HIGH_SLICE_INDEX(mm->context.slb_addr_limit); i++) { | 165 | for (i = 0; i < GET_HIGH_SLICE_INDEX(high_limit); i++) { |
161 | mask_index = i & 0x1; | 166 | mask_index = i & 0x1; |
162 | index = i >> 1; | 167 | index = i >> 1; |
163 | if (((hpsizes[index] >> (mask_index * 4)) & 0xf) == psize) | 168 | if (((hpsizes[index] >> (mask_index * 4)) & 0xf) == psize) |
@@ -169,6 +174,10 @@ static int slice_check_fit(struct mm_struct *mm, | |||
169 | struct slice_mask mask, struct slice_mask available) | 174 | struct slice_mask mask, struct slice_mask available) |
170 | { | 175 | { |
171 | DECLARE_BITMAP(result, SLICE_NUM_HIGH); | 176 | DECLARE_BITMAP(result, SLICE_NUM_HIGH); |
177 | /* | ||
178 | * Make sure we just do bit compare only to the max | ||
179 | * addr limit and not the full bit map size. | ||
180 | */ | ||
172 | unsigned long slice_count = GET_HIGH_SLICE_INDEX(mm->context.slb_addr_limit); | 181 | unsigned long slice_count = GET_HIGH_SLICE_INDEX(mm->context.slb_addr_limit); |
173 | 182 | ||
174 | bitmap_and(result, mask.high_slices, | 183 | bitmap_and(result, mask.high_slices, |
@@ -472,7 +481,7 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, | |||
472 | /* First make up a "good" mask of slices that have the right size | 481 | /* First make up a "good" mask of slices that have the right size |
473 | * already | 482 | * already |
474 | */ | 483 | */ |
475 | slice_mask_for_size(mm, psize, &good_mask); | 484 | slice_mask_for_size(mm, psize, &good_mask, high_limit); |
476 | slice_print_mask(" good_mask", good_mask); | 485 | slice_print_mask(" good_mask", good_mask); |
477 | 486 | ||
478 | /* | 487 | /* |
@@ -497,7 +506,7 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, | |||
497 | #ifdef CONFIG_PPC_64K_PAGES | 506 | #ifdef CONFIG_PPC_64K_PAGES |
498 | /* If we support combo pages, we can allow 64k pages in 4k slices */ | 507 | /* If we support combo pages, we can allow 64k pages in 4k slices */ |
499 | if (psize == MMU_PAGE_64K) { | 508 | if (psize == MMU_PAGE_64K) { |
500 | slice_mask_for_size(mm, MMU_PAGE_4K, &compat_mask); | 509 | slice_mask_for_size(mm, MMU_PAGE_4K, &compat_mask, high_limit); |
501 | if (fixed) | 510 | if (fixed) |
502 | slice_or_mask(&good_mask, &compat_mask); | 511 | slice_or_mask(&good_mask, &compat_mask); |
503 | } | 512 | } |
@@ -530,11 +539,11 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, | |||
530 | return newaddr; | 539 | return newaddr; |
531 | } | 540 | } |
532 | } | 541 | } |
533 | 542 | /* | |
534 | /* We don't fit in the good mask, check what other slices are | 543 | * We don't fit in the good mask, check what other slices are |
535 | * empty and thus can be converted | 544 | * empty and thus can be converted |
536 | */ | 545 | */ |
537 | slice_mask_for_free(mm, &potential_mask); | 546 | slice_mask_for_free(mm, &potential_mask, high_limit); |
538 | slice_or_mask(&potential_mask, &good_mask); | 547 | slice_or_mask(&potential_mask, &good_mask); |
539 | slice_print_mask(" potential", potential_mask); | 548 | slice_print_mask(" potential", potential_mask); |
540 | 549 | ||
@@ -744,17 +753,18 @@ int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, | |||
744 | { | 753 | { |
745 | struct slice_mask mask, available; | 754 | struct slice_mask mask, available; |
746 | unsigned int psize = mm->context.user_psize; | 755 | unsigned int psize = mm->context.user_psize; |
756 | unsigned long high_limit = mm->context.slb_addr_limit; | ||
747 | 757 | ||
748 | if (radix_enabled()) | 758 | if (radix_enabled()) |
749 | return 0; | 759 | return 0; |
750 | 760 | ||
751 | slice_range_to_mask(addr, len, &mask); | 761 | slice_range_to_mask(addr, len, &mask); |
752 | slice_mask_for_size(mm, psize, &available); | 762 | slice_mask_for_size(mm, psize, &available, high_limit); |
753 | #ifdef CONFIG_PPC_64K_PAGES | 763 | #ifdef CONFIG_PPC_64K_PAGES |
754 | /* We need to account for 4k slices too */ | 764 | /* We need to account for 4k slices too */ |
755 | if (psize == MMU_PAGE_64K) { | 765 | if (psize == MMU_PAGE_64K) { |
756 | struct slice_mask compat_mask; | 766 | struct slice_mask compat_mask; |
757 | slice_mask_for_size(mm, MMU_PAGE_4K, &compat_mask); | 767 | slice_mask_for_size(mm, MMU_PAGE_4K, &compat_mask, high_limit); |
758 | slice_or_mask(&available, &compat_mask); | 768 | slice_or_mask(&available, &compat_mask); |
759 | } | 769 | } |
760 | #endif | 770 | #endif |
diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 36344117c680..0ead3cd73caa 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c | |||
@@ -26,7 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | static DEFINE_MUTEX(nest_init_lock); | 27 | static DEFINE_MUTEX(nest_init_lock); |
28 | static DEFINE_PER_CPU(struct imc_pmu_ref *, local_nest_imc_refc); | 28 | static DEFINE_PER_CPU(struct imc_pmu_ref *, local_nest_imc_refc); |
29 | static struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; | 29 | static struct imc_pmu **per_nest_pmu_arr; |
30 | static cpumask_t nest_imc_cpumask; | 30 | static cpumask_t nest_imc_cpumask; |
31 | struct imc_pmu_ref *nest_imc_refc; | 31 | struct imc_pmu_ref *nest_imc_refc; |
32 | static int nest_pmus; | 32 | static int nest_pmus; |
@@ -286,13 +286,14 @@ static struct imc_pmu_ref *get_nest_pmu_ref(int cpu) | |||
286 | static void nest_change_cpu_context(int old_cpu, int new_cpu) | 286 | static void nest_change_cpu_context(int old_cpu, int new_cpu) |
287 | { | 287 | { |
288 | struct imc_pmu **pn = per_nest_pmu_arr; | 288 | struct imc_pmu **pn = per_nest_pmu_arr; |
289 | int i; | ||
290 | 289 | ||
291 | if (old_cpu < 0 || new_cpu < 0) | 290 | if (old_cpu < 0 || new_cpu < 0) |
292 | return; | 291 | return; |
293 | 292 | ||
294 | for (i = 0; *pn && i < IMC_MAX_PMUS; i++, pn++) | 293 | while (*pn) { |
295 | perf_pmu_migrate_context(&(*pn)->pmu, old_cpu, new_cpu); | 294 | perf_pmu_migrate_context(&(*pn)->pmu, old_cpu, new_cpu); |
295 | pn++; | ||
296 | } | ||
296 | } | 297 | } |
297 | 298 | ||
298 | static int ppc_nest_imc_cpu_offline(unsigned int cpu) | 299 | static int ppc_nest_imc_cpu_offline(unsigned int cpu) |
@@ -467,7 +468,7 @@ static int nest_imc_event_init(struct perf_event *event) | |||
467 | * Nest HW counter memory resides in a per-chip reserve-memory (HOMER). | 468 | * Nest HW counter memory resides in a per-chip reserve-memory (HOMER). |
468 | * Get the base memory addresss for this cpu. | 469 | * Get the base memory addresss for this cpu. |
469 | */ | 470 | */ |
470 | chip_id = topology_physical_package_id(event->cpu); | 471 | chip_id = cpu_to_chip_id(event->cpu); |
471 | pcni = pmu->mem_info; | 472 | pcni = pmu->mem_info; |
472 | do { | 473 | do { |
473 | if (pcni->id == chip_id) { | 474 | if (pcni->id == chip_id) { |
@@ -524,19 +525,19 @@ static int nest_imc_event_init(struct perf_event *event) | |||
524 | */ | 525 | */ |
525 | static int core_imc_mem_init(int cpu, int size) | 526 | static int core_imc_mem_init(int cpu, int size) |
526 | { | 527 | { |
527 | int phys_id, rc = 0, core_id = (cpu / threads_per_core); | 528 | int nid, rc = 0, core_id = (cpu / threads_per_core); |
528 | struct imc_mem_info *mem_info; | 529 | struct imc_mem_info *mem_info; |
529 | 530 | ||
530 | /* | 531 | /* |
531 | * alloc_pages_node() will allocate memory for core in the | 532 | * alloc_pages_node() will allocate memory for core in the |
532 | * local node only. | 533 | * local node only. |
533 | */ | 534 | */ |
534 | phys_id = topology_physical_package_id(cpu); | 535 | nid = cpu_to_node(cpu); |
535 | mem_info = &core_imc_pmu->mem_info[core_id]; | 536 | mem_info = &core_imc_pmu->mem_info[core_id]; |
536 | mem_info->id = core_id; | 537 | mem_info->id = core_id; |
537 | 538 | ||
538 | /* We need only vbase for core counters */ | 539 | /* We need only vbase for core counters */ |
539 | mem_info->vbase = page_address(alloc_pages_node(phys_id, | 540 | mem_info->vbase = page_address(alloc_pages_node(nid, |
540 | GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE | | 541 | GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE | |
541 | __GFP_NOWARN, get_order(size))); | 542 | __GFP_NOWARN, get_order(size))); |
542 | if (!mem_info->vbase) | 543 | if (!mem_info->vbase) |
@@ -797,14 +798,14 @@ static int core_imc_event_init(struct perf_event *event) | |||
797 | static int thread_imc_mem_alloc(int cpu_id, int size) | 798 | static int thread_imc_mem_alloc(int cpu_id, int size) |
798 | { | 799 | { |
799 | u64 ldbar_value, *local_mem = per_cpu(thread_imc_mem, cpu_id); | 800 | u64 ldbar_value, *local_mem = per_cpu(thread_imc_mem, cpu_id); |
800 | int phys_id = topology_physical_package_id(cpu_id); | 801 | int nid = cpu_to_node(cpu_id); |
801 | 802 | ||
802 | if (!local_mem) { | 803 | if (!local_mem) { |
803 | /* | 804 | /* |
804 | * This case could happen only once at start, since we dont | 805 | * This case could happen only once at start, since we dont |
805 | * free the memory in cpu offline path. | 806 | * free the memory in cpu offline path. |
806 | */ | 807 | */ |
807 | local_mem = page_address(alloc_pages_node(phys_id, | 808 | local_mem = page_address(alloc_pages_node(nid, |
808 | GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE | | 809 | GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE | |
809 | __GFP_NOWARN, get_order(size))); | 810 | __GFP_NOWARN, get_order(size))); |
810 | if (!local_mem) | 811 | if (!local_mem) |
@@ -1194,6 +1195,7 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr) | |||
1194 | kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs); | 1195 | kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs); |
1195 | kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]); | 1196 | kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]); |
1196 | kfree(pmu_ptr); | 1197 | kfree(pmu_ptr); |
1198 | kfree(per_nest_pmu_arr); | ||
1197 | return; | 1199 | return; |
1198 | } | 1200 | } |
1199 | 1201 | ||
@@ -1218,6 +1220,13 @@ static int imc_mem_init(struct imc_pmu *pmu_ptr, struct device_node *parent, | |||
1218 | return -ENOMEM; | 1220 | return -ENOMEM; |
1219 | 1221 | ||
1220 | /* Needed for hotplug/migration */ | 1222 | /* Needed for hotplug/migration */ |
1223 | if (!per_nest_pmu_arr) { | ||
1224 | per_nest_pmu_arr = kcalloc(get_max_nest_dev() + 1, | ||
1225 | sizeof(struct imc_pmu *), | ||
1226 | GFP_KERNEL); | ||
1227 | if (!per_nest_pmu_arr) | ||
1228 | return -ENOMEM; | ||
1229 | } | ||
1221 | per_nest_pmu_arr[pmu_index] = pmu_ptr; | 1230 | per_nest_pmu_arr[pmu_index] = pmu_ptr; |
1222 | break; | 1231 | break; |
1223 | case IMC_DOMAIN_CORE: | 1232 | case IMC_DOMAIN_CORE: |
diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c index 21f6531fae20..465ea105b771 100644 --- a/arch/powerpc/platforms/powernv/opal-imc.c +++ b/arch/powerpc/platforms/powernv/opal-imc.c | |||
@@ -153,6 +153,22 @@ static void disable_core_pmu_counters(void) | |||
153 | put_online_cpus(); | 153 | put_online_cpus(); |
154 | } | 154 | } |
155 | 155 | ||
156 | int get_max_nest_dev(void) | ||
157 | { | ||
158 | struct device_node *node; | ||
159 | u32 pmu_units = 0, type; | ||
160 | |||
161 | for_each_compatible_node(node, NULL, IMC_DTB_UNIT_COMPAT) { | ||
162 | if (of_property_read_u32(node, "type", &type)) | ||
163 | continue; | ||
164 | |||
165 | if (type == IMC_TYPE_CHIP) | ||
166 | pmu_units++; | ||
167 | } | ||
168 | |||
169 | return pmu_units; | ||
170 | } | ||
171 | |||
156 | static int opal_imc_counters_probe(struct platform_device *pdev) | 172 | static int opal_imc_counters_probe(struct platform_device *pdev) |
157 | { | 173 | { |
158 | struct device_node *imc_dev = pdev->dev.of_node; | 174 | struct device_node *imc_dev = pdev->dev.of_node; |
@@ -191,8 +207,10 @@ static int opal_imc_counters_probe(struct platform_device *pdev) | |||
191 | break; | 207 | break; |
192 | } | 208 | } |
193 | 209 | ||
194 | if (!imc_pmu_create(imc_dev, pmu_count, domain)) | 210 | if (!imc_pmu_create(imc_dev, pmu_count, domain)) { |
195 | pmu_count++; | 211 | if (domain == IMC_DOMAIN_NEST) |
212 | pmu_count++; | ||
213 | } | ||
196 | } | 214 | } |
197 | 215 | ||
198 | return 0; | 216 | return 0; |
diff --git a/arch/powerpc/platforms/powernv/vas.c b/arch/powerpc/platforms/powernv/vas.c index c488621dbec3..aebbe95c9230 100644 --- a/arch/powerpc/platforms/powernv/vas.c +++ b/arch/powerpc/platforms/powernv/vas.c | |||
@@ -135,6 +135,7 @@ int chip_to_vas_id(int chipid) | |||
135 | } | 135 | } |
136 | return -1; | 136 | return -1; |
137 | } | 137 | } |
138 | EXPORT_SYMBOL(chip_to_vas_id); | ||
138 | 139 | ||
139 | static int vas_probe(struct platform_device *pdev) | 140 | static int vas_probe(struct platform_device *pdev) |
140 | { | 141 | { |