Message ID | 20170206185015.12296-12-fu.wei@linaro.org (mailing list archive) |
---|---|
State | Not Applicable, archived |
Headers | show |
Hi, On Tue, Feb 07, 2017 at 02:50:13AM +0800, fu.wei@linaro.org wrote: > +static int __init gtdt_parse_timer_block(struct acpi_gtdt_timer_block *block, > + struct arch_timer_mem *data) Please s/data/timer_mem/ here, to match the rest of the timer code. > +{ > + int i, j; > + struct acpi_gtdt_timer_entry *frame; So as to make it clear what this is, and to make things a litlte simpler below, please s/frame/gtdt_frame/ here. > + > + if (!block->timer_count) { > + pr_err(FW_BUG "GT block present, but frame count is zero."); > + return -ENODEV; > + } > + > + if (block->timer_count > ARCH_TIMER_MEM_MAX_FRAMES) { > + pr_err(FW_BUG "GT block lists %d frames, ACPI spec only allows 8\n", > + block->timer_count); > + return -EINVAL; > + } > + > + data->cntctlbase = (phys_addr_t)block->block_address; > + /* > + * According to "Table * CNTCTLBase memory map" of > + * <ARM Architecture Reference Manual> for ARMv8, > + * The size of the CNTCTLBase frame is 4KB(Offset 0x000 – 0xFFC). > + */ As a general thing, please cite the version of the ARM ARM you're referring to, as over time the internal numbering (and the headings) change. e.g. /* * The CNTCTLBase frame is 4KB (register offsets 0x000 - 0xFFC). * See ARM DDI 0487A.k_iss10775, page I1-5129, Table I1-3 * "CNTCTLBase memory map". */ > + data->size = SZ_4K; > + > + frame = (void *)block + block->timer_offset; > + if (frame + block->timer_count != (void *)block + block->header.length) > + return -EINVAL; > + > + /* > + * Get the GT timer Frame data for every GT Block Timer > + */ > + for (i = 0, j = 0; i < block->timer_count; i++, frame++) { With the gtdt_frame rename as above, here we can do: struct arch_timer_mem_frame *frame = &timer_mem->frame[j]; > + if (frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER) > + continue; > + > + if (!frame->base_address || !frame->timer_interrupt) > + return -EINVAL; > + > + data->frame[j].phys_irq = map_gt_gsi(frame->timer_interrupt, > + frame->timer_flags); ... allowing us to simplify lines like this. Thanks, Mark. -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Mark, On 18 March 2017 at 03:40, Mark Rutland <mark.rutland@arm.com> wrote: > Hi, > > On Tue, Feb 07, 2017 at 02:50:13AM +0800, fu.wei@linaro.org wrote: >> +static int __init gtdt_parse_timer_block(struct acpi_gtdt_timer_block *block, >> + struct arch_timer_mem *data) > > Please s/data/timer_mem/ here, to match the rest of the timer code. > >> +{ >> + int i, j; >> + struct acpi_gtdt_timer_entry *frame; > > So as to make it clear what this is, and to make things a litlte simpler > below, please s/frame/gtdt_frame/ here. > >> + >> + if (!block->timer_count) { >> + pr_err(FW_BUG "GT block present, but frame count is zero."); >> + return -ENODEV; >> + } >> + >> + if (block->timer_count > ARCH_TIMER_MEM_MAX_FRAMES) { >> + pr_err(FW_BUG "GT block lists %d frames, ACPI spec only allows 8\n", >> + block->timer_count); >> + return -EINVAL; >> + } >> + >> + data->cntctlbase = (phys_addr_t)block->block_address; >> + /* >> + * According to "Table * CNTCTLBase memory map" of >> + * <ARM Architecture Reference Manual> for ARMv8, >> + * The size of the CNTCTLBase frame is 4KB(Offset 0x000 – 0xFFC). >> + */ > > As a general thing, please cite the version of the ARM ARM you're > referring to, as over time the internal numbering (and the headings) > change. > > e.g. > /* > * The CNTCTLBase frame is 4KB (register offsets 0x000 - 0xFFC). > * See ARM DDI 0487A.k_iss10775, page I1-5129, Table I1-3 > * "CNTCTLBase memory map". > */ > >> + data->size = SZ_4K; >> + >> + frame = (void *)block + block->timer_offset; >> + if (frame + block->timer_count != (void *)block + block->header.length) >> + return -EINVAL; >> + >> + /* >> + * Get the GT timer Frame data for every GT Block Timer >> + */ >> + for (i = 0, j = 0; i < block->timer_count; i++, frame++) { > > With the gtdt_frame rename as above, here we can do: > > struct arch_timer_mem_frame *frame = &timer_mem->frame[j]; > >> + if (frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER) >> + continue; >> + >> + if (!frame->base_address || !frame->timer_interrupt) >> + return -EINVAL; >> + >> + data->frame[j].phys_irq = map_gt_gsi(frame->timer_interrupt, >> + frame->timer_flags); > > ... allowing us to simplify lines like this. Thanks, will follow all the suggestion above. :-) > > Thanks, > Mark.
diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c index 8a03b4b..29b9acc 100644 --- a/drivers/acpi/arm64/gtdt.c +++ b/drivers/acpi/arm64/gtdt.c @@ -37,6 +37,28 @@ struct acpi_gtdt_descriptor { static struct acpi_gtdt_descriptor acpi_gtdt_desc __initdata; +static inline void *next_platform_timer(void *platform_timer) +{ + struct acpi_gtdt_header *gh = platform_timer; + + platform_timer += gh->length; + if (platform_timer < acpi_gtdt_desc.gtdt_end) + return platform_timer; + + return NULL; +} + +#define for_each_platform_timer(_g) \ + for (_g = acpi_gtdt_desc.platform_timer; _g; \ + _g = next_platform_timer(_g)) + +static inline bool is_timer_block(void *platform_timer) +{ + struct acpi_gtdt_header *gh = platform_timer; + + return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK; +} + static int __init map_gt_gsi(u32 interrupt, u32 flags) { int trigger, polarity; @@ -155,3 +177,109 @@ int __init acpi_gtdt_init(struct acpi_table_header *table, return ret; } + +static int __init gtdt_parse_timer_block(struct acpi_gtdt_timer_block *block, + struct arch_timer_mem *data) +{ + int i, j; + struct acpi_gtdt_timer_entry *frame; + + if (!block->timer_count) { + pr_err(FW_BUG "GT block present, but frame count is zero."); + return -ENODEV; + } + + if (block->timer_count > ARCH_TIMER_MEM_MAX_FRAMES) { + pr_err(FW_BUG "GT block lists %d frames, ACPI spec only allows 8\n", + block->timer_count); + return -EINVAL; + } + + data->cntctlbase = (phys_addr_t)block->block_address; + /* + * According to "Table * CNTCTLBase memory map" of + * <ARM Architecture Reference Manual> for ARMv8, + * The size of the CNTCTLBase frame is 4KB(Offset 0x000 – 0xFFC). + */ + data->size = SZ_4K; + + frame = (void *)block + block->timer_offset; + if (frame + block->timer_count != (void *)block + block->header.length) + return -EINVAL; + + /* + * Get the GT timer Frame data for every GT Block Timer + */ + for (i = 0, j = 0; i < block->timer_count; i++, frame++) { + if (frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER) + continue; + + if (!frame->base_address || !frame->timer_interrupt) + return -EINVAL; + + data->frame[j].phys_irq = map_gt_gsi(frame->timer_interrupt, + frame->timer_flags); + if (data->frame[j].phys_irq <= 0) { + pr_warn("failed to map physical timer irq in frame %d.\n", + i); + return -EINVAL; + } + + data->frame[j].virt_irq = + map_gt_gsi(frame->virtual_timer_interrupt, + frame->virtual_timer_flags); + if (data->frame[j].virt_irq <= 0) { + pr_warn("failed to map virtual timer irq in frame %d.\n", + i); + acpi_unregister_gsi(frame->timer_interrupt); + return -EINVAL; + } + + data->frame[j].frame_nr = frame->frame_number; + data->frame[j].cntbase = frame->base_address; + /* + * According to "Table * CNTBaseN memory map" of + * <ARM Architecture Reference Manual> for ARMv8, + * The size of the CNTBaseN frame is 4KB(Offset 0x000 – 0xFFC). + */ + data->frame[j].size = SZ_4K; + j++; + } + data->num_frames = j; + + return 0; +} + +/** + * acpi_arch_timer_mem_init() - Get the info of all GT blocks in GTDT table. + * @data: the pointer to the array of struct arch_timer_mem for returning + * the result of parsing. The element number of this array should + * be platform_timer_count(the total number of platform timers). + * @count: The pointer of int variate for returning the number of GT + * blocks we have parsed. + * + * Return: 0 if success, -EINVAL/-ENODEV if error. + */ +int __init acpi_arch_timer_mem_init(struct arch_timer_mem *data, + int *timer_count) +{ + int ret; + void *platform_timer; + + *timer_count = 0; + for_each_platform_timer(platform_timer) { + if (is_timer_block(platform_timer)) { + ret = gtdt_parse_timer_block(platform_timer, data); + if (ret) + return ret; + data++; + (*timer_count)++; + } + } + + if (*timer_count) + pr_info("found %d memory-mapped timer block(s).\n", + *timer_count); + + return 0; +} diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d0b271e..51e85b9 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -601,6 +601,7 @@ int acpi_reconfig_notifier_unregister(struct notifier_block *nb); int acpi_gtdt_init(struct acpi_table_header *table, int *platform_timer_count); int acpi_gtdt_map_ppi(int type); bool acpi_gtdt_c3stop(int type); +int acpi_arch_timer_mem_init(struct arch_timer_mem *data, int *timer_count); #endif #else /* !CONFIG_ACPI */