@@ -63,7 +63,16 @@ enum aspeed_lpc_snoop_index {
6363 ASPEED_LPC_SNOOP_INDEX_MAX = ASPEED_LPC_SNOOP_INDEX_1 ,
6464};
6565
66+ struct aspeed_lpc_snoop_channel_cfg {
67+ enum aspeed_lpc_snoop_index index ;
68+ u32 hicr5_en ;
69+ u32 snpwadr_mask ;
70+ u32 snpwadr_shift ;
71+ u32 hicrb_en ;
72+ };
73+
6674struct aspeed_lpc_snoop_channel {
75+ const struct aspeed_lpc_snoop_channel_cfg * cfg ;
6776 bool enabled ;
6877 struct kfifo fifo ;
6978 wait_queue_head_t wq ;
@@ -77,6 +86,23 @@ struct aspeed_lpc_snoop {
7786 struct aspeed_lpc_snoop_channel chan [ASPEED_LPC_SNOOP_INDEX_MAX + 1 ];
7887};
7988
89+ static const struct aspeed_lpc_snoop_channel_cfg channel_cfgs [ASPEED_LPC_SNOOP_INDEX_MAX + 1 ] = {
90+ {
91+ .index = ASPEED_LPC_SNOOP_INDEX_0 ,
92+ .hicr5_en = HICR5_EN_SNP0W | HICR5_ENINT_SNP0W ,
93+ .snpwadr_mask = SNPWADR_CH0_MASK ,
94+ .snpwadr_shift = SNPWADR_CH0_SHIFT ,
95+ .hicrb_en = HICRB_ENSNP0D ,
96+ },
97+ {
98+ .index = ASPEED_LPC_SNOOP_INDEX_1 ,
99+ .hicr5_en = HICR5_EN_SNP1W | HICR5_ENINT_SNP1W ,
100+ .snpwadr_mask = SNPWADR_CH1_MASK ,
101+ .snpwadr_shift = SNPWADR_CH1_SHIFT ,
102+ .hicrb_en = HICRB_ENSNP1D ,
103+ },
104+ };
105+
80106static struct aspeed_lpc_snoop_channel * snoop_file_to_chan (struct file * file )
81107{
82108 return container_of (file -> private_data ,
@@ -189,28 +215,27 @@ static int aspeed_lpc_snoop_config_irq(struct aspeed_lpc_snoop *lpc_snoop,
189215}
190216
191217__attribute__((nonnull ))
192- static int aspeed_lpc_enable_snoop (struct aspeed_lpc_snoop * lpc_snoop ,
193- struct device * dev ,
194- enum aspeed_lpc_snoop_index index , u16 lpc_port )
218+ static int aspeed_lpc_enable_snoop (struct device * dev ,
219+ struct aspeed_lpc_snoop * lpc_snoop ,
220+ struct aspeed_lpc_snoop_channel * channel ,
221+ const struct aspeed_lpc_snoop_channel_cfg * cfg ,
222+ u16 lpc_port )
195223{
196224 const struct aspeed_lpc_snoop_model_data * model_data ;
197- u32 hicr5_en , snpwadr_mask , snpwadr_shift , hicrb_en ;
198- struct aspeed_lpc_snoop_channel * channel ;
199225 int rc = 0 ;
200226
201- channel = & lpc_snoop -> chan [index ];
202-
203227 if (WARN_ON (channel -> enabled ))
204228 return - EBUSY ;
205229
206230 init_waitqueue_head (& channel -> wq );
207231
232+ channel -> cfg = cfg ;
208233 channel -> miscdev .minor = MISC_DYNAMIC_MINOR ;
209234 channel -> miscdev .fops = & snoop_fops ;
210235 channel -> miscdev .parent = dev ;
211236
212237 channel -> miscdev .name =
213- devm_kasprintf (dev , GFP_KERNEL , "%s%d" , DEVICE_NAME , index );
238+ devm_kasprintf (dev , GFP_KERNEL , "%s%d" , DEVICE_NAME , cfg -> index );
214239 if (!channel -> miscdev .name )
215240 return - ENOMEM ;
216241
@@ -223,69 +248,32 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
223248 goto err_free_fifo ;
224249
225250 /* Enable LPC snoop channel at requested port */
226- switch (index ) {
227- case 0 :
228- hicr5_en = HICR5_EN_SNP0W | HICR5_ENINT_SNP0W ;
229- snpwadr_mask = SNPWADR_CH0_MASK ;
230- snpwadr_shift = SNPWADR_CH0_SHIFT ;
231- hicrb_en = HICRB_ENSNP0D ;
232- break ;
233- case 1 :
234- hicr5_en = HICR5_EN_SNP1W | HICR5_ENINT_SNP1W ;
235- snpwadr_mask = SNPWADR_CH1_MASK ;
236- snpwadr_shift = SNPWADR_CH1_SHIFT ;
237- hicrb_en = HICRB_ENSNP1D ;
238- break ;
239- default :
240- rc = - EINVAL ;
241- goto err_misc_deregister ;
242- }
243-
244- regmap_update_bits (lpc_snoop -> regmap , HICR5 , hicr5_en , hicr5_en );
245- regmap_update_bits (lpc_snoop -> regmap , SNPWADR , snpwadr_mask ,
246- lpc_port << snpwadr_shift );
251+ regmap_set_bits (lpc_snoop -> regmap , HICR5 , cfg -> hicr5_en );
252+ regmap_update_bits (lpc_snoop -> regmap , SNPWADR , cfg -> snpwadr_mask ,
253+ lpc_port << cfg -> snpwadr_shift );
247254
248255 model_data = of_device_get_match_data (dev );
249256 if (model_data && model_data -> has_hicrb_ensnp )
250- regmap_update_bits (lpc_snoop -> regmap , HICRB , hicrb_en , hicrb_en );
257+ regmap_set_bits (lpc_snoop -> regmap , HICRB , cfg -> hicrb_en );
251258
252259 channel -> enabled = true;
253260
254261 return 0 ;
255262
256- err_misc_deregister :
257- misc_deregister (& channel -> miscdev );
258263err_free_fifo :
259264 kfifo_free (& channel -> fifo );
260265 return rc ;
261266}
262267
263268__attribute__((nonnull ))
264269static void aspeed_lpc_disable_snoop (struct aspeed_lpc_snoop * lpc_snoop ,
265- enum aspeed_lpc_snoop_index index )
270+ struct aspeed_lpc_snoop_channel * channel )
266271{
267- struct aspeed_lpc_snoop_channel * channel ;
268-
269- channel = & lpc_snoop -> chan [index ];
270-
271272 if (!channel -> enabled )
272273 return ;
273274
274275 /* Disable interrupts along with the device */
275- switch (index ) {
276- case 0 :
277- regmap_update_bits (lpc_snoop -> regmap , HICR5 ,
278- HICR5_EN_SNP0W | HICR5_ENINT_SNP0W ,
279- 0 );
280- break ;
281- case 1 :
282- regmap_update_bits (lpc_snoop -> regmap , HICR5 ,
283- HICR5_EN_SNP1W | HICR5_ENINT_SNP1W ,
284- 0 );
285- break ;
286- default :
287- return ;
288- }
276+ regmap_clear_bits (lpc_snoop -> regmap , HICR5 , channel -> cfg -> hicr5_en );
289277
290278 channel -> enabled = false;
291279 /* Consider improving safety wrt concurrent reader(s) */
@@ -298,8 +286,8 @@ static void aspeed_lpc_snoop_remove(struct platform_device *pdev)
298286 struct aspeed_lpc_snoop * lpc_snoop = dev_get_drvdata (& pdev -> dev );
299287
300288 /* Disable both snoop channels */
301- aspeed_lpc_disable_snoop (lpc_snoop , ASPEED_LPC_SNOOP_INDEX_0 );
302- aspeed_lpc_disable_snoop (lpc_snoop , ASPEED_LPC_SNOOP_INDEX_1 );
289+ aspeed_lpc_disable_snoop (lpc_snoop , & lpc_snoop -> chan [ 0 ] );
290+ aspeed_lpc_disable_snoop (lpc_snoop , & lpc_snoop -> chan [ 1 ] );
303291}
304292
305293static int aspeed_lpc_snoop_probe (struct platform_device * pdev )
@@ -338,14 +326,17 @@ static int aspeed_lpc_snoop_probe(struct platform_device *pdev)
338326 if (rc )
339327 return rc ;
340328
329+ static_assert (ARRAY_SIZE (channel_cfgs ) == ARRAY_SIZE (lpc_snoop -> chan ),
330+ "Broken implementation assumption regarding cfg count" );
341331 for (idx = ASPEED_LPC_SNOOP_INDEX_0 ; idx <= ASPEED_LPC_SNOOP_INDEX_MAX ; idx ++ ) {
342332 u32 port ;
343333
344334 rc = of_property_read_u32_index (dev -> of_node , "snoop-ports" , idx , & port );
345335 if (rc )
346336 break ;
347337
348- rc = aspeed_lpc_enable_snoop (lpc_snoop , dev , idx , port );
338+ rc = aspeed_lpc_enable_snoop (dev , lpc_snoop , & lpc_snoop -> chan [idx ],
339+ & channel_cfgs [idx ], port );
349340 if (rc )
350341 goto cleanup_channels ;
351342 }
0 commit comments