66 * Copyright (c) 2012 Guenter Roeck
77 */
88
9+ #include <linux/atomic.h>
910#include <linux/debugfs.h>
1011#include <linux/delay.h>
1112#include <linux/dcache.h>
2122#include <linux/pmbus.h>
2223#include <linux/regulator/driver.h>
2324#include <linux/regulator/machine.h>
24- #include <linux/of.h>
2525#include <linux/thermal.h>
26+ #include <linux/workqueue.h>
2627#include "pmbus.h"
2728
2829/*
@@ -112,6 +113,11 @@ struct pmbus_data {
112113
113114 struct mutex update_lock ;
114115
116+ #if IS_ENABLED (CONFIG_REGULATOR )
117+ atomic_t regulator_events [PMBUS_PAGES ];
118+ struct work_struct regulator_notify_work ;
119+ #endif
120+
115121 bool has_status_word ; /* device uses STATUS_WORD register */
116122 int (* read_status )(struct i2c_client * client , int page );
117123
@@ -3228,12 +3234,19 @@ static int pmbus_regulator_get_voltage(struct regulator_dev *rdev)
32283234 .class = PSC_VOLTAGE_OUT ,
32293235 .convert = true,
32303236 };
3237+ int ret ;
32313238
3239+ mutex_lock (& data -> update_lock );
32323240 s .data = _pmbus_read_word_data (client , s .page , 0xff , PMBUS_READ_VOUT );
3233- if (s .data < 0 )
3234- return s .data ;
3241+ if (s .data < 0 ) {
3242+ ret = s .data ;
3243+ goto unlock ;
3244+ }
32353245
3236- return (int )pmbus_reg2data (data , & s ) * 1000 ; /* unit is uV */
3246+ ret = (int )pmbus_reg2data (data , & s ) * 1000 ; /* unit is uV */
3247+ unlock :
3248+ mutex_unlock (& data -> update_lock );
3249+ return ret ;
32373250}
32383251
32393252static int pmbus_regulator_set_voltage (struct regulator_dev * rdev , int min_uv ,
@@ -3250,16 +3263,22 @@ static int pmbus_regulator_set_voltage(struct regulator_dev *rdev, int min_uv,
32503263 };
32513264 int val = DIV_ROUND_CLOSEST (min_uv , 1000 ); /* convert to mV */
32523265 int low , high ;
3266+ int ret ;
32533267
32543268 * selector = 0 ;
32553269
3270+ mutex_lock (& data -> update_lock );
32563271 low = pmbus_regulator_get_low_margin (client , s .page );
3257- if (low < 0 )
3258- return low ;
3272+ if (low < 0 ) {
3273+ ret = low ;
3274+ goto unlock ;
3275+ }
32593276
32603277 high = pmbus_regulator_get_high_margin (client , s .page );
3261- if (high < 0 )
3262- return high ;
3278+ if (high < 0 ) {
3279+ ret = high ;
3280+ goto unlock ;
3281+ }
32633282
32643283 /* Make sure we are within margins */
32653284 if (low > val )
@@ -3269,7 +3288,10 @@ static int pmbus_regulator_set_voltage(struct regulator_dev *rdev, int min_uv,
32693288
32703289 val = pmbus_data2reg (data , & s , val );
32713290
3272- return _pmbus_write_word_data (client , s .page , PMBUS_VOUT_COMMAND , (u16 )val );
3291+ ret = _pmbus_write_word_data (client , s .page , PMBUS_VOUT_COMMAND , (u16 )val );
3292+ unlock :
3293+ mutex_unlock (& data -> update_lock );
3294+ return ret ;
32733295}
32743296
32753297static int pmbus_regulator_list_voltage (struct regulator_dev * rdev ,
@@ -3279,6 +3301,7 @@ static int pmbus_regulator_list_voltage(struct regulator_dev *rdev,
32793301 struct i2c_client * client = to_i2c_client (dev -> parent );
32803302 struct pmbus_data * data = i2c_get_clientdata (client );
32813303 int val , low , high ;
3304+ int ret ;
32823305
32833306 if (data -> flags & PMBUS_VOUT_PROTECTED )
32843307 return 0 ;
@@ -3291,18 +3314,29 @@ static int pmbus_regulator_list_voltage(struct regulator_dev *rdev,
32913314 val = DIV_ROUND_CLOSEST (rdev -> desc -> min_uV +
32923315 (rdev -> desc -> uV_step * selector ), 1000 ); /* convert to mV */
32933316
3317+ mutex_lock (& data -> update_lock );
3318+
32943319 low = pmbus_regulator_get_low_margin (client , rdev_get_id (rdev ));
3295- if (low < 0 )
3296- return low ;
3320+ if (low < 0 ) {
3321+ ret = low ;
3322+ goto unlock ;
3323+ }
32973324
32983325 high = pmbus_regulator_get_high_margin (client , rdev_get_id (rdev ));
3299- if (high < 0 )
3300- return high ;
3326+ if (high < 0 ) {
3327+ ret = high ;
3328+ goto unlock ;
3329+ }
33013330
3302- if (val >= low && val <= high )
3303- return val * 1000 ; /* unit is uV */
3331+ if (val >= low && val <= high ) {
3332+ ret = val * 1000 ; /* unit is uV */
3333+ goto unlock ;
3334+ }
33043335
3305- return 0 ;
3336+ ret = 0 ;
3337+ unlock :
3338+ mutex_unlock (& data -> update_lock );
3339+ return ret ;
33063340}
33073341
33083342const struct regulator_ops pmbus_regulator_ops = {
@@ -3333,12 +3367,42 @@ int pmbus_regulator_init_cb(struct regulator_dev *rdev,
33333367}
33343368EXPORT_SYMBOL_NS_GPL (pmbus_regulator_init_cb , "PMBUS" );
33353369
3370+ static void pmbus_regulator_notify_work_cancel (void * data )
3371+ {
3372+ struct pmbus_data * pdata = data ;
3373+
3374+ cancel_work_sync (& pdata -> regulator_notify_work );
3375+ }
3376+
3377+ static void pmbus_regulator_notify_worker (struct work_struct * work )
3378+ {
3379+ struct pmbus_data * data =
3380+ container_of (work , struct pmbus_data , regulator_notify_work );
3381+ int i , j ;
3382+
3383+ for (i = 0 ; i < data -> info -> pages ; i ++ ) {
3384+ int event ;
3385+
3386+ event = atomic_xchg (& data -> regulator_events [i ], 0 );
3387+ if (!event )
3388+ continue ;
3389+
3390+ for (j = 0 ; j < data -> info -> num_regulators ; j ++ ) {
3391+ if (i == rdev_get_id (data -> rdevs [j ])) {
3392+ regulator_notifier_call_chain (data -> rdevs [j ],
3393+ event , NULL );
3394+ break ;
3395+ }
3396+ }
3397+ }
3398+ }
3399+
33363400static int pmbus_regulator_register (struct pmbus_data * data )
33373401{
33383402 struct device * dev = data -> dev ;
33393403 const struct pmbus_driver_info * info = data -> info ;
33403404 const struct pmbus_platform_data * pdata = dev_get_platdata (dev );
3341- int i ;
3405+ int i , ret ;
33423406
33433407 data -> rdevs = devm_kzalloc (dev , sizeof (struct regulator_dev * ) * info -> num_regulators ,
33443408 GFP_KERNEL );
@@ -3362,19 +3426,19 @@ static int pmbus_regulator_register(struct pmbus_data *data)
33623426 info -> reg_desc [i ].name );
33633427 }
33643428
3429+ INIT_WORK (& data -> regulator_notify_work , pmbus_regulator_notify_worker );
3430+
3431+ ret = devm_add_action_or_reset (dev , pmbus_regulator_notify_work_cancel , data );
3432+ if (ret )
3433+ return ret ;
3434+
33653435 return 0 ;
33663436}
33673437
33683438static void pmbus_regulator_notify (struct pmbus_data * data , int page , int event )
33693439{
3370- int j ;
3371-
3372- for (j = 0 ; j < data -> info -> num_regulators ; j ++ ) {
3373- if (page == rdev_get_id (data -> rdevs [j ])) {
3374- regulator_notifier_call_chain (data -> rdevs [j ], event , NULL );
3375- break ;
3376- }
3377- }
3440+ atomic_or (event , & data -> regulator_events [page ]);
3441+ schedule_work (& data -> regulator_notify_work );
33783442}
33793443#else
33803444static int pmbus_regulator_register (struct pmbus_data * data )
0 commit comments