Skip to content

Commit fdf003f

Browse files
committed
soc: aspeed: lpc-snoop: Lift channel config to const structs
The shifts and masks for each channel are defined by hardware and are not something that changes at runtime. Accordingly, describe the information in an array of const structs and associate elements with each channel instance, removing the need for the switch and handling of its default case. Link: https://patch.msgid.link/20250616-aspeed-lpc-snoop-fixes-v2-10-3cdd59c934d3@codeconstruct.com.au Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
1 parent 4483e3c commit fdf003f

1 file changed

Lines changed: 45 additions & 54 deletions

File tree

drivers/soc/aspeed/aspeed-lpc-snoop.c

Lines changed: 45 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
6674
struct 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+
80106
static 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);
258263
err_free_fifo:
259264
kfifo_free(&channel->fifo);
260265
return rc;
261266
}
262267

263268
__attribute__((nonnull))
264269
static 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

305293
static 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

Comments
 (0)