lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Fri, 20 Jul 2012 07:08:15 +0000
From:	"Kim, Milo" <Milo.Kim@...com>
To:	Mark Brown <broonie@...nsource.wolfsonmicro.com>
CC:	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: RE: [PATCH 1/2] regmap-irq: use mask and val rather than using
 mask_buf_def

> On Thu, Jul 19, 2012 at 09:04:39AM +0000, Kim, Milo wrote:
> > Default mask value is used when updating irq registers.
> > Rather than using mask_buf_def[], use mask and value explicitly.
> 
> Why?  What is the problem you are seeing and what is the intended
> effect
> of this change?

There are two reasons for this patch.
One is for better understanding about masking and updated bits.
The other is related with supporting interrupt-unmasked device.

(a) 'mask_buf & val_buf' VS 'mask_buf_def & mask_buf'
In my opinion, the mask_buf_def[] is 'masking bit' and the mask_buf[] is the 'value' to be updated when the IRQ is enabled/disabled.
The mask_buf_def[] means which bit is updated - that is exactly *mask bit*.
The value of mask_buf_def[] is copied from mask_buf[] when regmap_add_irq_chip() is called.
And then mask_buf_def[] is fixed value.
On the other hand, the mask_buf[] is variable. The value is updated whenever the IRQ is enabled/disabled.
Which is better understandable terminology ? 'mask and value' or 'default mask and updated mask'
I think 'mask & value' is more clear.

(b) supporting interrupt-unmasked device
There is different interrupt concept from interrupt-masked device.
To enable the IRQ, the register bit should be 1.
To update this value, the bit of IRQ value should be separated from the mask bit.

< Example >
Let me assume that enabling the IRQ0 and IRQ1 ... (8 bits register based)

(Interrupt mask device)
IRQ7 | IRQ6 | IRQ5 | IRQ4 | IRQ3 | IRQ2 | IRQ1 | IRQ0
 1      1      1      1      1      1      0      0
Mask  = 0xFC
Value = 0xFC (same as mask bit)

(Interrupt unmask device)
IRQ7 | IRQ6 | IRQ5 | IRQ4 | IRQ3 | IRQ2 | IRQ1 | IRQ0
 0      0      0      0      0      0      1      1
Mask  = 0xFC
Value = 0x03 (different from mask bit)

Let's move to regmap_irq data structure with two types.

(Interrupt mask device)
static struct regmap_irq foo_irqs[] = {
	[FOO_IRQ0] = {
		.reg_offset =  0;
		.mask = BIT(0), /* 0x01 */
	},
	[FOO_IRQ1] = {
		.reg_offset =  0;
		.mask = BIT(1), /* 0x02 */
	},
};

                   Initial time      irq_enable()  irq_enable()
 Value        (regmap_add_irq_chip)   with IRQ0     with IRQ1
_______________________________________________________________
mask_buf_def       0x03                0x03          0x03
mask_buf           0x03                0xFE          0xFD
updated bits    0000 0011           xxxx xxx0      xxxx xx0x
            (IRQ0,1 disabled)     (IRQ0 enabled)  (IRQ1 enabled)

Result: Works well.
        Only one bit is cleared when the IRQ is enabled.

(Interrupt unmask device)
Case 1)
static struct regmap_irq foo_irqs[] = {
	[FOO_IRQ0] = {
		.reg_offset =  0;
		.mask = BIT(0), /* 0x01 */
	},
	[FOO_IRQ1] = {
		.reg_offset =  0;
		.mask = BIT(1), /* 0x02 */
	},
};

                   Initial time      irq_enable()  irq_enable()
 Value        (regmap_add_irq_chip)   with IRQ0     with IRQ1
_______________________________________________________________
mask_buf_def       0x03                0x03          0x03
mask_buf           0x03                0xFE          0xFD
updated bits    0000 0011           xxxx xxx0      xxxx xx0x
            (IRQ0,1 enabled)     (IRQ0 disabled) (IRQ1 disabled)

Result: Not working.
        Each IRQ is disabled. Other bits can be enabled not intentionally.

Case 2) What if changing the 'mask' to inverted bit as following.
static struct regmap_irq foo_irqs[] = {
	[FOO_IRQ0] = {
		.reg_offset =  0;
		.mask = ~BIT(0), /* 0xFE */
	},
	[FOO_IRQ1] = {
		.reg_offset =  0;
		.mask = ~BIT(1), /* 0xFD */
	},
};

                   Initial time      irq_enable()  irq_enable()
 Value        (regmap_add_irq_chip)   with IRQ0     with IRQ1
_______________________________________________________________
mask_buf_def       0xFF                0xFF          0xFF
mask_buf           0xFF                0x01          0x02
updated bits    1111 1111           0000 0001      0000 0010
         (All IRQs are enabled)  (IRQ0 enabled,  (IRQ1 enabled,
                                  others are      but others are disabled)
                                  disabled)

Result: Not working.
        Other bits are cleared except flagged IRQ.
        Only one IRQ exists. Others are ignored. 

In both cases, it doesn't work with interrupt-unmasked-register scheme.
To fix this issue, two patches were sent.
The mask and value should be separated -- (1) and different bit operation is required -- (2).
(1) [PATCH 1/2] regmap-irq: use mask and val rather than using mask_buf_def
(2) [PATCH 2/2] regmap-irq: support different type of irq register

And then the result will be as following.

(Interrupt mask device)

                   Initial time      irq_enable()  irq_enable()
 Value        (regmap_add_irq_chip)   with IRQ0     with IRQ1
_______________________________________________________________
mask_buf           0x03                0x03          0x03
val_buf             -                  0xFE          0xFD
updated bits     0000 0011           xxxx xxx0     xxxx xx0x
             (IRQ0,1 disabled)    (IRQ0 enabled)  (IRQ1 enabled)

(Interrupt unmask device)

                   Initial time      irq_enable()  irq_enable()
 Value        (regmap_add_irq_chip)   with IRQ0     with IRQ1
_______________________________________________________________
mask_buf           0x03                0x03          0x03
val_buf             -                  0x01          0x02
updated bits     1111 1100           xxxx xxx1     xxxx xx1x
             (IRQ0,1 disabled)    (IRQ0 enabled)  (IRQ1 enabled)


I'm not sure there is another device which supports the interrupt-unmasked register.
As far as I know, LP8788 is the only device :-(

Thanks !

Best Regards,
Milo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ