From: Grazvydas Ignotas Date: Mon, 16 Feb 2015 19:48:18 +0000 (+0200) Subject: leds-twl4030-pwm, pandora_bl: fix a race between the two X-Git-Tag: sz_173~55 X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=commitdiff_plain;h=071cd8e3b4013c8a5b4ed7ebade8752da5cb936a;hp=e2517977596b7faff87f410b1b254676a0941383 leds-twl4030-pwm, pandora_bl: fix a race between the two Both were doing rmw at startup, so some bits were getting lost. --- diff --git a/drivers/leds/leds-twl4030-pwm.c b/drivers/leds/leds-twl4030-pwm.c index 705750e62e8c..f6d656ed414d 100644 --- a/drivers/leds/leds-twl4030-pwm.c +++ b/drivers/leds/leds-twl4030-pwm.c @@ -55,21 +55,6 @@ struct twl4030_pwmled { struct work_struct work; }; -static int twl4030_clear_set(u8 mod_no, u8 clear, u8 set, u8 reg) -{ - u8 val = 0; - int ret; - - ret = twl_i2c_read_u8(mod_no, &val, reg); - if (ret) - return ret; - - val &= ~clear; - val |= set; - - return twl_i2c_write_u8(mod_no, val, reg); -} - static void twl4030_enable_ledab(enum twl4030_led led, bool enable) { u8 bits; @@ -80,14 +65,14 @@ static void twl4030_enable_ledab(enum twl4030_led led, bool enable) bits = LEDEN_LEDBON | LEDEN_LEDBPWM; if (enable) - twl4030_clear_set(TWL4030_MODULE_LED, 0, bits, TWL4030_LED_LEDEN); + twl_i2c_rmw_u8(TWL4030_MODULE_LED, 0, bits, TWL4030_LED_LEDEN); else - twl4030_clear_set(TWL4030_MODULE_LED, bits, 0, TWL4030_LED_LEDEN); + twl_i2c_rmw_u8(TWL4030_MODULE_LED, bits, 0, TWL4030_LED_LEDEN); } static void twl4030_enable_pwm01(enum twl4030_led led, bool enable) { - u8 r, enbit, clkbit; + u8 enbit, clkbit; if (led == TWL4030_PWM0) { enbit = GPBR1_PWM0_ENABLE; @@ -97,22 +82,19 @@ static void twl4030_enable_pwm01(enum twl4030_led led, bool enable) clkbit = GPBR1_PWM1_CLK_ENABLE; } - twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1); - if (enable) { /* first enable clock, then PWM out */ - r &= ~enbit; - r |= clkbit; - twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1); - r |= enbit; + twl_i2c_rmw_u8(TWL4030_MODULE_INTBR, + enbit, clkbit, TWL_INTBR_GPBR1); + twl_i2c_rmw_u8(TWL4030_MODULE_INTBR, + 0, enbit, TWL_INTBR_GPBR1); } else { /* first disable PWM output, then clock */ - r &= ~enbit; - twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1); - r &= ~clkbit; + twl_i2c_rmw_u8(TWL4030_MODULE_INTBR, + enbit, 0, TWL_INTBR_GPBR1); + twl_i2c_rmw_u8(TWL4030_MODULE_INTBR, + clkbit, 0, TWL_INTBR_GPBR1); } - - twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1); } static void twl4030_pwmled_work(struct work_struct *work) @@ -189,18 +171,18 @@ static int __devinit twl4030_pwmled_probe(struct platform_device *pdev) led->module = TWL4030_MODULE_PWM0; led->enable = twl4030_enable_pwm01; /* enable PWM0 in pin mux */ - twl4030_clear_set(TWL4030_MODULE_INTBR, + twl_i2c_rmw_u8(TWL4030_MODULE_INTBR, 0x0c, 0x04, TWL_INTBR_PMBR1); /* enable PWM clock for initial write */ - twl4030_clear_set(TWL4030_MODULE_INTBR, + twl_i2c_rmw_u8(TWL4030_MODULE_INTBR, 0, GPBR1_PWM0_CLK_ENABLE, TWL_INTBR_GPBR1); break; case TWL4030_PWM1: led->module = TWL4030_MODULE_PWM1; led->enable = twl4030_enable_pwm01; - twl4030_clear_set(TWL4030_MODULE_INTBR, + twl_i2c_rmw_u8(TWL4030_MODULE_INTBR, 0, 0x30, TWL_INTBR_PMBR1); - twl4030_clear_set(TWL4030_MODULE_INTBR, + twl_i2c_rmw_u8(TWL4030_MODULE_INTBR, 0, GPBR1_PWM1_CLK_ENABLE, TWL_INTBR_GPBR1); break; default: diff --git a/drivers/video/backlight/pandora_bl.c b/drivers/video/backlight/pandora_bl.c index 4ec30748b447..1187c2c00000 100644 --- a/drivers/video/backlight/pandora_bl.c +++ b/drivers/video/backlight/pandora_bl.c @@ -40,7 +40,6 @@ static int pandora_backlight_update_status(struct backlight_device *bl) { int brightness = bl->props.brightness; - u8 r; if (bl->props.power != FB_BLANK_UNBLANK) brightness = 0; @@ -57,12 +56,10 @@ static int pandora_backlight_update_status(struct backlight_device *bl) goto done; /* first disable PWM0 output, then clock */ - twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1); - r &= ~PWM0_ENABLE; - twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1); - r &= ~PWM0_CLK_ENABLE; - twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1); - + twl_i2c_rmw_u8(TWL4030_MODULE_INTBR, PWM0_ENABLE, 0, + TWL_INTBR_GPBR1); + twl_i2c_rmw_u8(TWL4030_MODULE_INTBR, PWM0_CLK_ENABLE, 0, + TWL_INTBR_GPBR1); goto done; } @@ -75,12 +72,10 @@ static int pandora_backlight_update_status(struct backlight_device *bl) TWL_PWM0_OFF); /* first enable clock, then PWM0 out */ - twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1); - r &= ~PWM0_ENABLE; - r |= PWM0_CLK_ENABLE; - twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1); - r |= PWM0_ENABLE; - twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1); + twl_i2c_rmw_u8(TWL4030_MODULE_INTBR, + PWM0_ENABLE, PWM0_CLK_ENABLE, TWL_INTBR_GPBR1); + twl_i2c_rmw_u8(TWL4030_MODULE_INTBR, + 0, PWM0_ENABLE, TWL_INTBR_GPBR1); /* * TI made it very easy to enable digital control, so easy that @@ -117,7 +112,6 @@ static int pandora_backlight_probe(struct platform_device *pdev) { struct backlight_properties props; struct backlight_device *bl; - u8 r; memset(&props, 0, sizeof(props)); props.max_brightness = MAX_USER_VALUE; @@ -139,10 +133,8 @@ static int pandora_backlight_probe(struct platform_device *pdev) backlight_update_status(bl); /* enable PWM function in pin mux */ - twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_PMBR1); - r &= ~TWL_PMBR1_PWM0_MUXMASK; - r |= TWL_PMBR1_PWM0; - twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_PMBR1); + twl_i2c_rmw_u8(TWL4030_MODULE_INTBR, + TWL_PMBR1_PWM0_MUXMASK, TWL_PMBR1_PWM0, TWL_INTBR_PMBR1); return 0; }