[PATCH 2/4] pinctrl: exynos: Add irq_chip instance for Exynos7 wakeup interrupts
Abhilash Kesavan
kesavan.abhilash at gmail.com
Tue Sep 23 00:04:33 PDT 2014
Hi Tomasz,
On Mon, Sep 22, 2014 at 1:25 PM, Tomasz Figa <tomasz.figa at gmail.com> wrote:
> On 22.09.2014 08:17, Abhilash Kesavan wrote:
>> Hi Tomasz,
>>
>> On Sat, Sep 13, 2014 at 4:57 PM, Tomasz Figa <tomasz.figa at gmail.com> wrote:
>>> Hi Abhilash,
>>>
>>> Please see my comments inline.
>>>
>>> On 13.09.2014 10:50, Abhilash Kesavan wrote:
>>>> Exynos7 uses different offsets for wakeup interrupt configuration registers.
>>>> So a new irq_chip instance for Exynos7 wakeup interrupts is added. The irq_chip
>>>> selection is now based on the wakeup interrupt controller compatible string.
>>>
>>> [snip]
>>>
>>>> @@ -328,9 +322,11 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
>>>> /*
>>>> * irq_chip for wakeup interrupts
>>>> */
>>>> -static struct exynos_irq_chip exynos_wkup_irq_chip = {
>>>> +static struct exynos_irq_chip exynos_wkup_irq_chip;
>>>> +
>>>
>>> Why do you still need this, if you have both variants below?
>>
>> After adding __initdata to the two variants, I will require to have a
>> copy of one of them.
>>
>>>
>>>> +static struct exynos_irq_chip exynos4210_wkup_irq_chip = {
>>>> .chip = {
>>>> - .name = "exynos_wkup_irq_chip",
>>>> + .name = "exynos4210_wkup_irq_chip",
>>>> .irq_unmask = exynos_irq_unmask,
>>>> .irq_mask = exynos_irq_mask,
>>>> .irq_ack = exynos_irq_ack,
>>>> @@ -342,6 +338,29 @@ static struct exynos_irq_chip exynos_wkup_irq_chip = {
>>>> .eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
>>>> };
>>>>
>>>> +static struct exynos_irq_chip exynos7_wkup_irq_chip = {
>>>> + .chip = {
>>>> + .name = "exynos7_wkup_irq_chip",
>>>> + .irq_unmask = exynos_irq_unmask,
>>>> + .irq_mask = exynos_irq_mask,
>>>> + .irq_ack = exynos_irq_ack,
>>>> + .irq_set_type = exynos_irq_set_type,
>>>> + .irq_set_wake = exynos_wkup_irq_set_wake,
>>>> + },
>>>> + .eint_con = EXYNOS7_WKUP_ECON_OFFSET,
>>>> + .eint_mask = EXYNOS7_WKUP_EMASK_OFFSET,
>>>> + .eint_pend = EXYNOS7_WKUP_EPEND_OFFSET,
>>>> +};
>>>> +
>>>> +/* list of external wakeup controllers supported */
>>>> +static const struct of_device_id exynos_wkup_irq_ids[] = {
>>>> + { .compatible = "samsung,exynos4210-wakeup-eint",
>>>> + .data = &exynos4210_wkup_irq_chip },
>>>> + { .compatible = "samsung,exynos7-wakeup-eint",
>>>> + .data = &exynos7_wkup_irq_chip },
>>>> + { }
>>>> +};
>>>> +
>>>> /* interrupt handler for wakeup interrupts 0..15 */
>>>> static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
>>>> {
>>>> @@ -434,7 +453,12 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
>>>> int idx, irq;
>>>>
>>>> for_each_child_of_node(dev->of_node, np) {
>>>> - if (of_match_node(exynos_wkup_irq_ids, np)) {
>>>> + const struct of_device_id *match;
>>>> +
>>>> + match = of_match_node(exynos_wkup_irq_ids, np);
>>>> + if (match) {
>>>> + memcpy(&exynos_wkup_irq_chip, match->data,
>>>> + sizeof(struct exynos_irq_chip));
>>>
>>> Hmm, this doesn't look correct to me. You are modifying a static struct
>>> here. Why couldn't you simply use the exynos irq chip pointed by
>>> match->data in further registration code?
>>
>> That will not be available later once I use __initdata.
>>
>
> Then either __initdata shouldn't be necessary or kmemdup() should be
> used to allocate a copy.
Will fix this and send out a new version soon.
Regards,
Abhilash
>
>>>
>>>> wkup_np = np;
>>>> break;
>>>> }
>>>> diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h
>>>> index e060722..0db1e52 100644
>>>> --- a/drivers/pinctrl/samsung/pinctrl-exynos.h
>>>> +++ b/drivers/pinctrl/samsung/pinctrl-exynos.h
>>>> @@ -25,6 +25,9 @@
>>>> #define EXYNOS_WKUP_ECON_OFFSET 0xE00
>>>> #define EXYNOS_WKUP_EMASK_OFFSET 0xF00
>>>> #define EXYNOS_WKUP_EPEND_OFFSET 0xF40
>>>> +#define EXYNOS7_WKUP_ECON_OFFSET 0x700
>>>> +#define EXYNOS7_WKUP_EMASK_OFFSET 0x900
>>>> +#define EXYNOS7_WKUP_EPEND_OFFSET 0xA00
>>>
>>> Interestingly enough, the offsets look just like the normal GPIO
>>> interrupt controller of previous Exynos SoCs. Are you sure those are
>>> correct? Also if somehow the controller now resembles the normal one,
>>> doesn't it have the SVC register making it possible to reuse the non
>>> wake-up code instead?
>>
>> The wakeup interrupt register offsets are the same as the GPIO
>> interrupt offsets in earlier Exynos SoCs. There is no SVC register for
>> the wakeup interrupt block.
>
> OK, your code is fine then.
>
> Best regards,
> Tomasz
More information about the linux-arm-kernel
mailing list