2727#define REG_POWERON 0x85
2828#define REG_PWM 0x86
2929
30+ struct attiny_lcd {
31+ /* lock to serialise overall accesses to the Atmel */
32+ struct mutex lock ;
33+ struct regmap * regmap ;
34+ };
35+
3036static const struct regmap_config attiny_regmap_config = {
3137 .reg_bits = 8 ,
3238 .val_bits = 8 ,
39+ .disable_locking = 1 ,
3340 .max_register = REG_PWM ,
3441 .cache_type = REGCACHE_NONE ,
3542};
3643
3744static int attiny_lcd_power_enable (struct regulator_dev * rdev )
3845{
46+ struct mutex * lock = rdev_get_drvdata (rdev );
3947 unsigned int data ;
4048 int ret , i ;
4149
50+ mutex_lock (lock );
51+
4252 regmap_write (rdev -> regmap , REG_POWERON , 1 );
4353 msleep (80 );
4454
@@ -63,33 +73,49 @@ static int attiny_lcd_power_enable(struct regulator_dev *rdev)
6373 */
6474 regmap_write (rdev -> regmap , REG_PORTA , BIT (2 ));
6575
76+ mutex_unlock (lock );
77+
6678 return 0 ;
6779}
6880
6981static int attiny_lcd_power_disable (struct regulator_dev * rdev )
7082{
83+ struct mutex * lock = rdev_get_drvdata (rdev );
84+
85+ mutex_lock (lock );
86+
7187 regmap_write (rdev -> regmap , REG_PWM , 0 );
7288 regmap_write (rdev -> regmap , REG_POWERON , 0 );
7389 msleep (30 );
90+
91+ mutex_unlock (lock );
92+
7493 return 0 ;
7594}
7695
7796static int attiny_lcd_power_is_enabled (struct regulator_dev * rdev )
7897{
98+ struct mutex * lock = rdev_get_drvdata (rdev );
7999 unsigned int data ;
80100 int ret , i ;
81101
102+ mutex_lock (lock );
103+
82104 for (i = 0 ; i < 10 ; i ++ ) {
83105 ret = regmap_read (rdev -> regmap , REG_POWERON , & data );
84106 if (!ret )
85107 break ;
86108 usleep_range (10000 , 12000 );
87109 }
88- if (ret < 0 )
110+ if (ret < 0 ) {
111+ mutex_unlock (lock );
89112 return ret ;
113+ }
90114
91- if (!(data & BIT (0 )))
115+ if (!(data & BIT (0 ))) {
116+ mutex_unlock (lock );
92117 return 0 ;
118+ }
93119
94120 for (i = 0 ; i < 10 ; i ++ ) {
95121 ret = regmap_read (rdev -> regmap , REG_PORTB , & data );
@@ -98,6 +124,8 @@ static int attiny_lcd_power_is_enabled(struct regulator_dev *rdev)
98124 usleep_range (10000 , 12000 );
99125 }
100126
127+ mutex_unlock (lock );
128+
101129 if (ret < 0 )
102130 return ret ;
103131
@@ -125,10 +153,13 @@ static const struct regulator_desc attiny_regulator = {
125153
126154static int attiny_update_status (struct backlight_device * bl )
127155{
128- struct regmap * regmap = bl_get_data (bl );
156+ struct attiny_lcd * state = bl_get_data (bl );
157+ struct regmap * regmap = state -> regmap ;
129158 int brightness = bl -> props .brightness ;
130159 int ret , i ;
131160
161+ mutex_lock (& state -> lock );
162+
132163 if (bl -> props .power != FB_BLANK_UNBLANK ||
133164 bl -> props .fb_blank != FB_BLANK_UNBLANK )
134165 brightness = 0 ;
@@ -139,20 +170,27 @@ static int attiny_update_status(struct backlight_device *bl)
139170 break ;
140171 }
141172
173+ mutex_unlock (& state -> lock );
174+
142175 return ret ;
143176}
144177
145178static int attiny_get_brightness (struct backlight_device * bl )
146179{
147- struct regmap * regmap = bl_get_data (bl );
180+ struct attiny_lcd * state = bl_get_data (bl );
181+ struct regmap * regmap = state -> regmap ;
148182 int ret , brightness , i ;
149183
184+ mutex_lock (& state -> lock );
185+
150186 for (i = 0 ; i < 10 ; i ++ ) {
151187 ret = regmap_read (regmap , REG_PWM , & brightness );
152188 if (!ret )
153189 break ;
154190 }
155191
192+ mutex_unlock (& state -> lock );
193+
156194 if (ret )
157195 return ret ;
158196
@@ -174,22 +212,30 @@ static int attiny_i2c_probe(struct i2c_client *i2c,
174212 struct regulator_config config = { };
175213 struct backlight_device * bl ;
176214 struct regulator_dev * rdev ;
215+ struct attiny_lcd * state ;
177216 struct regmap * regmap ;
178217 unsigned int data ;
179218 int ret ;
180219
220+ state = devm_kzalloc (& i2c -> dev , sizeof (* state ), GFP_KERNEL );
221+ if (!state )
222+ return - ENOMEM ;
223+
224+ mutex_init (& state -> lock );
225+ i2c_set_clientdata (i2c , state );
226+
181227 regmap = devm_regmap_init_i2c (i2c , & attiny_regmap_config );
182228 if (IS_ERR (regmap )) {
183229 ret = PTR_ERR (regmap );
184230 dev_err (& i2c -> dev , "Failed to allocate register map: %d\n" ,
185231 ret );
186- return ret ;
232+ goto error ;
187233 }
188234
189235 ret = regmap_read (regmap , REG_ID , & data );
190236 if (ret < 0 ) {
191237 dev_err (& i2c -> dev , "Failed to read REG_ID reg: %d\n" , ret );
192- return ret ;
238+ goto error ;
193239 }
194240
195241 switch (data ) {
@@ -198,7 +244,8 @@ static int attiny_i2c_probe(struct i2c_client *i2c,
198244 break ;
199245 default :
200246 dev_err (& i2c -> dev , "Unknown Atmel firmware revision: 0x%02x\n" , data );
201- return - ENODEV ;
247+ ret = - ENODEV ;
248+ goto error ;
202249 }
203250
204251 regmap_write (regmap , REG_POWERON , 0 );
@@ -208,23 +255,44 @@ static int attiny_i2c_probe(struct i2c_client *i2c,
208255 config .regmap = regmap ;
209256 config .of_node = i2c -> dev .of_node ;
210257 config .init_data = & attiny_regulator_default ;
258+ config .driver_data = & state -> lock ;
211259
212260 rdev = devm_regulator_register (& i2c -> dev , & attiny_regulator , & config );
213261 if (IS_ERR (rdev )) {
214262 dev_err (& i2c -> dev , "Failed to register ATTINY regulator\n" );
215- return PTR_ERR (rdev );
263+ ret = PTR_ERR (rdev );
264+ goto error ;
216265 }
217266
218267 props .type = BACKLIGHT_RAW ;
219268 props .max_brightness = 0xff ;
269+
270+ state -> regmap = regmap ;
271+
220272 bl = devm_backlight_device_register (& i2c -> dev , dev_name (& i2c -> dev ),
221- & i2c -> dev , regmap , & attiny_bl ,
273+ & i2c -> dev , state , & attiny_bl ,
222274 & props );
223- if (IS_ERR (bl ))
224- return PTR_ERR (bl );
275+ if (IS_ERR (bl )) {
276+ ret = PTR_ERR (bl );
277+ goto error ;
278+ }
225279
226280 bl -> props .brightness = 0xff ;
227281
282+ return 0 ;
283+
284+ error :
285+ mutex_destroy (& state -> lock );
286+
287+ return ret ;
288+ }
289+
290+ static int attiny_i2c_remove (struct i2c_client * client )
291+ {
292+ struct attiny_lcd * state = i2c_get_clientdata (client );
293+
294+ mutex_destroy (& state -> lock );
295+
228296 return 0 ;
229297}
230298
@@ -240,6 +308,7 @@ static struct i2c_driver attiny_regulator_driver = {
240308 .of_match_table = of_match_ptr (attiny_dt_ids ),
241309 },
242310 .probe = attiny_i2c_probe ,
311+ .remove = attiny_i2c_remove ,
243312};
244313
245314module_i2c_driver (attiny_regulator_driver );
0 commit comments