Skip to content

Commit 78ca0c0

Browse files
amboarcminyard
authored andcommitted
ipmi: kcs_bmc_aspeed: Use of match data to extract KCS properties
Unpack and remove the aspeed_kcs_probe_of_v[12]() functions to aid rearranging how the private device-driver memory is allocated. Signed-off-by: Andrew Jeffery <andrew@aj.id.au> Message-Id: <20210608104757.582199-2-andrew@aj.id.au> Reviewed-by: Zev Weiss <zweiss@equinix.com> Signed-off-by: Corey Minyard <cminyard@mvista.com>
1 parent 2253042 commit 78ca0c0

1 file changed

Lines changed: 76 additions & 76 deletions

File tree

drivers/char/ipmi/kcs_bmc_aspeed.c

Lines changed: 76 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/module.h>
1414
#include <linux/of.h>
1515
#include <linux/of_address.h>
16+
#include <linux/of_device.h>
1617
#include <linux/platform_device.h>
1718
#include <linux/poll.h>
1819
#include <linux/regmap.h>
@@ -63,6 +64,10 @@ struct aspeed_kcs_bmc {
6364
struct regmap *map;
6465
};
6566

67+
struct aspeed_kcs_of_ops {
68+
int (*get_channel)(struct platform_device *pdev);
69+
int (*get_io_address)(struct platform_device *pdev);
70+
};
6671

6772
static u8 aspeed_kcs_inb(struct kcs_bmc *kcs_bmc, u32 reg)
6873
{
@@ -231,119 +236,92 @@ static const struct kcs_ioreg ast_kcs_bmc_ioregs[KCS_CHANNEL_MAX] = {
231236
{ .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 },
232237
};
233238

234-
static struct kcs_bmc *aspeed_kcs_probe_of_v1(struct platform_device *pdev)
239+
static int aspeed_kcs_of_v1_get_channel(struct platform_device *pdev)
235240
{
236-
struct aspeed_kcs_bmc *priv;
237241
struct device_node *np;
238-
struct kcs_bmc *kcs;
239242
u32 channel;
240-
u32 slave;
241243
int rc;
242244

243245
np = pdev->dev.of_node;
244246

245247
rc = of_property_read_u32(np, "kcs_chan", &channel);
246248
if ((rc != 0) || (channel == 0 || channel > KCS_CHANNEL_MAX)) {
247249
dev_err(&pdev->dev, "no valid 'kcs_chan' configured\n");
248-
return ERR_PTR(-EINVAL);
249-
}
250-
251-
kcs = kcs_bmc_alloc(&pdev->dev, sizeof(struct aspeed_kcs_bmc), channel);
252-
if (!kcs)
253-
return ERR_PTR(-ENOMEM);
254-
255-
priv = kcs_bmc_priv(kcs);
256-
priv->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
257-
if (IS_ERR(priv->map)) {
258-
dev_err(&pdev->dev, "Couldn't get regmap\n");
259-
return ERR_PTR(-ENODEV);
260-
}
261-
262-
rc = of_property_read_u32(np, "kcs_addr", &slave);
263-
if (rc) {
264-
dev_err(&pdev->dev, "no valid 'kcs_addr' configured\n");
265-
return ERR_PTR(-EINVAL);
250+
return -EINVAL;
266251
}
267252

268-
kcs->ioreg = ast_kcs_bmc_ioregs[channel - 1];
269-
aspeed_kcs_set_address(kcs, slave);
270-
271-
return kcs;
253+
return channel;
272254
}
273255

274-
static int aspeed_kcs_calculate_channel(const struct kcs_ioreg *regs)
256+
static int aspeed_kcs_of_v1_get_io_address(struct platform_device *pdev)
275257
{
276-
int i;
258+
u32 slave;
259+
int rc;
277260

278-
for (i = 0; i < ARRAY_SIZE(ast_kcs_bmc_ioregs); i++) {
279-
if (!memcmp(&ast_kcs_bmc_ioregs[i], regs, sizeof(*regs)))
280-
return i + 1;
261+
rc = of_property_read_u32(pdev->dev.of_node, "kcs_addr", &slave);
262+
if (rc || slave > 0xffff) {
263+
dev_err(&pdev->dev, "no valid 'kcs_addr' configured\n");
264+
return -EINVAL;
281265
}
282266

283-
return -EINVAL;
267+
return slave;
284268
}
285269

286-
static struct kcs_bmc *aspeed_kcs_probe_of_v2(struct platform_device *pdev)
270+
static int aspeed_kcs_of_v2_get_channel(struct platform_device *pdev)
287271
{
288-
struct aspeed_kcs_bmc *priv;
289272
struct device_node *np;
290273
struct kcs_ioreg ioreg;
291-
struct kcs_bmc *kcs;
292274
const __be32 *reg;
293-
int channel;
294-
u32 slave;
295-
int rc;
275+
int i;
296276

297277
np = pdev->dev.of_node;
298278

299279
/* Don't translate addresses, we want offsets for the regmaps */
300280
reg = of_get_address(np, 0, NULL, NULL);
301281
if (!reg)
302-
return ERR_PTR(-EINVAL);
282+
return -EINVAL;
303283
ioreg.idr = be32_to_cpup(reg);
304284

305285
reg = of_get_address(np, 1, NULL, NULL);
306286
if (!reg)
307-
return ERR_PTR(-EINVAL);
287+
return -EINVAL;
308288
ioreg.odr = be32_to_cpup(reg);
309289

310290
reg = of_get_address(np, 2, NULL, NULL);
311291
if (!reg)
312-
return ERR_PTR(-EINVAL);
292+
return -EINVAL;
313293
ioreg.str = be32_to_cpup(reg);
314294

315-
channel = aspeed_kcs_calculate_channel(&ioreg);
316-
if (channel < 0)
317-
return ERR_PTR(channel);
295+
for (i = 0; i < ARRAY_SIZE(ast_kcs_bmc_ioregs); i++) {
296+
if (!memcmp(&ast_kcs_bmc_ioregs[i], &ioreg, sizeof(ioreg)))
297+
return i + 1;
298+
}
318299

319-
kcs = kcs_bmc_alloc(&pdev->dev, sizeof(struct aspeed_kcs_bmc), channel);
320-
if (!kcs)
321-
return ERR_PTR(-ENOMEM);
300+
return -EINVAL;
301+
}
322302

323-
kcs->ioreg = ioreg;
303+
static int aspeed_kcs_of_v2_get_io_address(struct platform_device *pdev)
304+
{
305+
uint32_t slave;
306+
int rc;
324307

325-
priv = kcs_bmc_priv(kcs);
326-
priv->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
327-
if (IS_ERR(priv->map)) {
328-
dev_err(&pdev->dev, "Couldn't get regmap\n");
329-
return ERR_PTR(-ENODEV);
308+
rc = of_property_read_u32(pdev->dev.of_node, "aspeed,lpc-io-reg", &slave);
309+
if (rc || slave > 0xffff) {
310+
dev_err(&pdev->dev, "no valid 'aspeed,lpc-io-reg' configured\n");
311+
return -EINVAL;
330312
}
331313

332-
rc = of_property_read_u32(np, "aspeed,lpc-io-reg", &slave);
333-
if (rc)
334-
return ERR_PTR(rc);
335-
336-
aspeed_kcs_set_address(kcs, slave);
337-
338-
return kcs;
314+
return slave;
339315
}
340316

341317
static int aspeed_kcs_probe(struct platform_device *pdev)
342318
{
319+
const struct aspeed_kcs_of_ops *ops;
343320
struct device *dev = &pdev->dev;
321+
struct aspeed_kcs_bmc *priv;
344322
struct kcs_bmc *kcs_bmc;
345323
struct device_node *np;
346-
int rc;
324+
int rc, channel, addr;
347325

348326
np = dev->of_node->parent;
349327
if (!of_device_is_compatible(np, "aspeed,ast2400-lpc-v2") &&
@@ -352,23 +330,35 @@ static int aspeed_kcs_probe(struct platform_device *pdev)
352330
dev_err(dev, "unsupported LPC device binding\n");
353331
return -ENODEV;
354332
}
355-
356-
np = dev->of_node;
357-
if (of_device_is_compatible(np, "aspeed,ast2400-kcs-bmc") ||
358-
of_device_is_compatible(np, "aspeed,ast2500-kcs-bmc"))
359-
kcs_bmc = aspeed_kcs_probe_of_v1(pdev);
360-
else if (of_device_is_compatible(np, "aspeed,ast2400-kcs-bmc-v2") ||
361-
of_device_is_compatible(np, "aspeed,ast2500-kcs-bmc-v2"))
362-
kcs_bmc = aspeed_kcs_probe_of_v2(pdev);
363-
else
333+
ops = of_device_get_match_data(&pdev->dev);
334+
if (!ops)
364335
return -EINVAL;
365336

366-
if (IS_ERR(kcs_bmc))
367-
return PTR_ERR(kcs_bmc);
337+
channel = ops->get_channel(pdev);
338+
if (channel < 0)
339+
return channel;
340+
341+
kcs_bmc = kcs_bmc_alloc(&pdev->dev, sizeof(struct aspeed_kcs_bmc), channel);
342+
if (!kcs_bmc)
343+
return -ENOMEM;
368344

345+
kcs_bmc->ioreg = ast_kcs_bmc_ioregs[channel - 1];
369346
kcs_bmc->io_inputb = aspeed_kcs_inb;
370347
kcs_bmc->io_outputb = aspeed_kcs_outb;
371348

349+
addr = ops->get_io_address(pdev);
350+
if (addr < 0)
351+
return addr;
352+
353+
priv = kcs_bmc_priv(kcs_bmc);
354+
priv->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
355+
if (IS_ERR(priv->map)) {
356+
dev_err(&pdev->dev, "Couldn't get regmap\n");
357+
return -ENODEV;
358+
}
359+
360+
aspeed_kcs_set_address(kcs_bmc, addr);
361+
372362
rc = aspeed_kcs_config_irq(kcs_bmc, pdev);
373363
if (rc)
374364
return rc;
@@ -400,11 +390,21 @@ static int aspeed_kcs_remove(struct platform_device *pdev)
400390
return 0;
401391
}
402392

393+
static const struct aspeed_kcs_of_ops of_v1_ops = {
394+
.get_channel = aspeed_kcs_of_v1_get_channel,
395+
.get_io_address = aspeed_kcs_of_v1_get_io_address,
396+
};
397+
398+
static const struct aspeed_kcs_of_ops of_v2_ops = {
399+
.get_channel = aspeed_kcs_of_v2_get_channel,
400+
.get_io_address = aspeed_kcs_of_v2_get_io_address,
401+
};
402+
403403
static const struct of_device_id ast_kcs_bmc_match[] = {
404-
{ .compatible = "aspeed,ast2400-kcs-bmc" },
405-
{ .compatible = "aspeed,ast2500-kcs-bmc" },
406-
{ .compatible = "aspeed,ast2400-kcs-bmc-v2" },
407-
{ .compatible = "aspeed,ast2500-kcs-bmc-v2" },
404+
{ .compatible = "aspeed,ast2400-kcs-bmc", .data = &of_v1_ops },
405+
{ .compatible = "aspeed,ast2500-kcs-bmc", .data = &of_v1_ops },
406+
{ .compatible = "aspeed,ast2400-kcs-bmc-v2", .data = &of_v2_ops },
407+
{ .compatible = "aspeed,ast2500-kcs-bmc-v2", .data = &of_v2_ops },
408408
{ }
409409
};
410410
MODULE_DEVICE_TABLE(of, ast_kcs_bmc_match);

0 commit comments

Comments
 (0)