On Fri, Aug 3, 2012 at 5:27 PM, Sylwester Nawrocki
<[email protected]> wrote:
> Hi Jonathan,
>
> On 08/03/2012 10:05 PM, Jonathan Kliegman wrote:
>> The interupt combiner registers need to be saved on suspend and restored
>> on resume or combiner-based intterupts won't work after resume.
>
> intterupts -> interrupts
Thanks, will fix.
>
>> Signed-off-by: Jonathan Kliegman<[email protected]>
>> ---
>> arch/arm/mach-exynos/common.c | 74
>> +++++++++++++++++++++++++++++++++++++----
>> 1 files changed, 67 insertions(+), 7 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
>> index 4eb39cd..af296e5 100644
>> --- a/arch/arm/mach-exynos/common.c
>> +++ b/arch/arm/mach-exynos/common.c
>> @@ -22,6 +22,7 @@
>> #include<linux/export.h>
>> #include<linux/irqdomain.h>
>> #include<linux/of_address.h>
>> +#include<linux/cpu_pm.h>
>>
>> #include<asm/proc-fns.h>
>> #include<asm/exception.h>
>> @@ -405,10 +406,14 @@ struct combiner_chip_data {
>> unsigned int irq_offset;
>> unsigned int irq_mask;
>> void __iomem *base;
>> +#ifdef CONFIG_CPU_PM
>> + bool saved_on;
>> +#endif
>> };
>>
>> static struct irq_domain *combiner_irq_domain;
>> static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
>> +static unsigned int rt_max_combiner_nr;
>>
>> static inline void __iomem *combiner_base(struct irq_data *data)
>> {
>> @@ -535,6 +540,55 @@ static int combiner_irq_domain_map(struct irq_domain
>> *d, unsigned int irq,
>> return 0;
>> }
>>
>> +#ifdef CONFIG_CPU_PM
>> +static void combiner_save(void)
>> +{
>> + int i;
>> +
>> + for (i = 0; i< rt_max_combiner_nr; i++) {
>> + if (combiner_data[i].irq_mask&
>> + __raw_readl(combiner_data[i].base + COMBINER_ENABLE_SET)) {
>> + combiner_data[i].saved_on = true;
>> + } else {
>> + combiner_data[i].saved_on = false;
>> + }
>> + }
>> +}
>> +
>> +static void combiner_restore(void)
>> +{
>> + int i;
>> +
>> + for (i = 0; i< rt_max_combiner_nr; i++) {
>> + if (!combiner_data[i].saved_on)
>> + continue;
>> +
>> + __raw_writel(combiner_data[i].irq_mask,
>> + combiner_data[i].base + COMBINER_ENABLE_SET);
>> + }
>> +}
>> +
>> +
>> +static int combiner_notifier(struct notifier_block *self, unsigned long cmd,
>> + void *v)
>> +{
>> + switch (cmd) {
>> + case CPU_CLUSTER_PM_ENTER:
>> + combiner_save();
>> + break;
>> + case CPU_CLSUTER_PM_EXIT:
>
> Looks like this part of code wasn't compiled or some last minute changes
> introduced this typo ?
I had tested it (compiled and ran) but on a different branch. The
typo must have been introduced when I manually rebased against head.
Thanks for catching this.
>
>> + combiner_restore();
>> + break;
>> + }
>> +
>> + return NOTIFY_OK;
>> +}
>> +
>> +static struct notifier_block combiner_notifier_block = {
>> + .notifier_call = combiner_notifier,
>> +};
>> +#endif
>> +
>> static struct irq_domain_ops combiner_irq_domain_ops = {
>> .xlate = combiner_irq_domain_xlate,
>> .map = combiner_irq_domain_map,
>> @@ -544,20 +598,21 @@ static void __init combiner_init(void __iomem
>> *combiner_base,
>> struct device_node *np)
>> {
>> int i, irq, irq_base;
>> - unsigned int max_nr, nr_irq;
>> + unsigned int nr_irq;
>>
>> if (np) {
>> - if (of_property_read_u32(np, "samsung,combiner-nr",&max_nr)) {
>> + if (of_property_read_u32(np, "samsung,combiner-nr",
>> + &rt_max_combiner_nr)) {
>> pr_warning("%s: number of combiners not specified, "
>> "setting default as %d.\n",
>> __func__, EXYNOS4_MAX_COMBINER_NR);
>> - max_nr = EXYNOS4_MAX_COMBINER_NR;
>> + rt_max_combiner_nr = EXYNOS4_MAX_COMBINER_NR;
>> }
>> } else {
>> - max_nr = soc_is_exynos5250() ? EXYNOS5_MAX_COMBINER_NR :
>> - EXYNOS4_MAX_COMBINER_NR;
>> + rt_max_combiner_nr = soc_is_exynos5250() ?
>> + EXYNOS5_MAX_COMBINER_NR : EXYNOS4_MAX_COMBINER_NR;
>> }
>> - nr_irq = max_nr * MAX_IRQ_IN_COMBINER;
>> + nr_irq = rt_max_combiner_nr * MAX_IRQ_IN_COMBINER;
>>
>> irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0);
>> if (IS_ERR_VALUE(irq_base)) {
>> @@ -572,7 +627,7 @@ static void __init combiner_init(void __iomem
>> *combiner_base,
>> return;
>> }
>>
>> - for (i = 0; i< max_nr; i++) {
>> + for (i = 0; i< rt_max_combiner_nr; i++) {
>> combiner_init_one(i, combiner_base + (i>> 2) * 0x10);
>> irq = IRQ_SPI(i);
>> #ifdef CONFIG_OF
>> @@ -581,6 +636,11 @@ static void __init combiner_init(void __iomem
>> *combiner_base,
>> #endif
>> combiner_cascade_irq(i, irq);
>> }
>> +
>> +#ifdef CONFIG_PM
>
> Shouldn't this also be CONFIG_CPU_PM ? Declaration of combiner_notifier_block
> is compiled in only when CONFIG_CPU_PM is defined.
Correct, in fixing the previous two I missed this one. Will fix and
update patch.
Thanks for catching these.
>
>> + /* Setup suspend/resume combiner saving */
>> + cpu_pm_register_notifier(&combiner_notifier_block);
>> +#endif
>> }
>>
>> #ifdef CONFIG_OF
>
> Thanks,
> Sylwester
--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html