aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/kempld-core.c
diff options
context:
space:
mode:
authorMichael Brunner <mibru@gmx.de>2014-04-08 02:21:06 -0400
committerLee Jones <lee.jones@linaro.org>2014-06-03 03:11:11 -0400
commit58a9e5b98360e8dcf9c958c0552fb35279e3933f (patch)
tree0783e2632b01ab28f40ebe0ae8f781989f4b3e04 /drivers/mfd/kempld-core.c
parented612a349c967dd235d83959f9a0878777a5ae18 (diff)
mfd: Add sysfs attributes for Kontron PLD firmware revision
This patch adds attributes to the Kontron PLD driver to allow applications to retrieve firmware information. Additionally the format has been changed to conform with the representation in other Kontron software. Signed-off-by: Michael Brunner <michael.brunner@kontron.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/mfd/kempld-core.c')
-rw-r--r--drivers/mfd/kempld-core.c127
1 files changed, 106 insertions, 21 deletions
diff --git a/drivers/mfd/kempld-core.c b/drivers/mfd/kempld-core.c
index 07692604e119..25c5ca6797da 100644
--- a/drivers/mfd/kempld-core.c
+++ b/drivers/mfd/kempld-core.c
@@ -288,9 +288,38 @@ EXPORT_SYMBOL_GPL(kempld_release_mutex);
288 */ 288 */
289static int kempld_get_info(struct kempld_device_data *pld) 289static int kempld_get_info(struct kempld_device_data *pld)
290{ 290{
291 int ret;
291 struct kempld_platform_data *pdata = dev_get_platdata(pld->dev); 292 struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
293 char major, minor;
294
295 ret = pdata->get_info(pld);
296 if (ret)
297 return ret;
298
299 /* The Kontron PLD firmware version string has the following format:
300 * Pwxy.zzzz
301 * P: Fixed
302 * w: PLD number - 1 hex digit
303 * x: Major version - 1 alphanumerical digit (0-9A-V)
304 * y: Minor version - 1 alphanumerical digit (0-9A-V)
305 * zzzz: Build number - 4 zero padded hex digits */
292 306
293 return pdata->get_info(pld); 307 if (pld->info.major < 10)
308 major = pld->info.major + '0';
309 else
310 major = (pld->info.major - 10) + 'A';
311 if (pld->info.minor < 10)
312 minor = pld->info.minor + '0';
313 else
314 minor = (pld->info.minor - 10) + 'A';
315
316 ret = scnprintf(pld->info.version, sizeof(pld->info.version),
317 "P%X%c%c.%04X", pld->info.number, major, minor,
318 pld->info.buildnr);
319 if (ret < 0)
320 return ret;
321
322 return 0;
294} 323}
295 324
296/* 325/*
@@ -307,9 +336,71 @@ static int kempld_register_cells(struct kempld_device_data *pld)
307 return pdata->register_cells(pld); 336 return pdata->register_cells(pld);
308} 337}
309 338
339static const char *kempld_get_type_string(struct kempld_device_data *pld)
340{
341 const char *version_type;
342
343 switch (pld->info.type) {
344 case 0:
345 version_type = "release";
346 break;
347 case 1:
348 version_type = "debug";
349 break;
350 case 2:
351 version_type = "custom";
352 break;
353 default:
354 version_type = "unspecified";
355 break;
356 }
357
358 return version_type;
359}
360
361static ssize_t kempld_version_show(struct device *dev,
362 struct device_attribute *attr, char *buf)
363{
364 struct kempld_device_data *pld = dev_get_drvdata(dev);
365
366 return scnprintf(buf, PAGE_SIZE, "%s\n", pld->info.version);
367}
368
369static ssize_t kempld_specification_show(struct device *dev,
370 struct device_attribute *attr, char *buf)
371{
372 struct kempld_device_data *pld = dev_get_drvdata(dev);
373
374 return scnprintf(buf, PAGE_SIZE, "%d.%d\n", pld->info.spec_major,
375 pld->info.spec_minor);
376}
377
378static ssize_t kempld_type_show(struct device *dev,
379 struct device_attribute *attr, char *buf)
380{
381 struct kempld_device_data *pld = dev_get_drvdata(dev);
382
383 return scnprintf(buf, PAGE_SIZE, "%s\n", kempld_get_type_string(pld));
384}
385
386static DEVICE_ATTR(pld_version, S_IRUGO, kempld_version_show, NULL);
387static DEVICE_ATTR(pld_specification, S_IRUGO, kempld_specification_show,
388 NULL);
389static DEVICE_ATTR(pld_type, S_IRUGO, kempld_type_show, NULL);
390
391static struct attribute *pld_attributes[] = {
392 &dev_attr_pld_version.attr,
393 &dev_attr_pld_specification.attr,
394 &dev_attr_pld_type.attr,
395 NULL
396};
397
398static const struct attribute_group pld_attr_group = {
399 .attrs = pld_attributes,
400};
401
310static int kempld_detect_device(struct kempld_device_data *pld) 402static int kempld_detect_device(struct kempld_device_data *pld)
311{ 403{
312 char *version_type;
313 u8 index_reg; 404 u8 index_reg;
314 int ret; 405 int ret;
315 406
@@ -335,27 +426,19 @@ static int kempld_detect_device(struct kempld_device_data *pld)
335 if (ret) 426 if (ret)
336 return ret; 427 return ret;
337 428
338 switch (pld->info.type) { 429 dev_info(pld->dev, "Found Kontron PLD - %s (%s), spec %d.%d\n",
339 case 0: 430 pld->info.version, kempld_get_type_string(pld),
340 version_type = "release"; 431 pld->info.spec_major, pld->info.spec_minor);
341 break; 432
342 case 1: 433 ret = sysfs_create_group(&pld->dev->kobj, &pld_attr_group);
343 version_type = "debug"; 434 if (ret)
344 break; 435 return ret;
345 case 2:
346 version_type = "custom";
347 break;
348 default:
349 version_type = "unspecified";
350 }
351 436
352 dev_info(pld->dev, "Found Kontron PLD %d\n", pld->info.number); 437 ret = kempld_register_cells(pld);
353 dev_info(pld->dev, "%s version %d.%d build %d, specification %d.%d\n", 438 if (ret)
354 version_type, pld->info.major, pld->info.minor, 439 sysfs_remove_group(&pld->dev->kobj, &pld_attr_group);
355 pld->info.buildnr, pld->info.spec_major,
356 pld->info.spec_minor);
357 440
358 return kempld_register_cells(pld); 441 return ret;
359} 442}
360 443
361static int kempld_probe(struct platform_device *pdev) 444static int kempld_probe(struct platform_device *pdev)
@@ -399,6 +482,8 @@ static int kempld_remove(struct platform_device *pdev)
399 struct kempld_device_data *pld = platform_get_drvdata(pdev); 482 struct kempld_device_data *pld = platform_get_drvdata(pdev);
400 struct kempld_platform_data *pdata = dev_get_platdata(pld->dev); 483 struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
401 484
485 sysfs_remove_group(&pld->dev->kobj, &pld_attr_group);
486
402 mfd_remove_devices(&pdev->dev); 487 mfd_remove_devices(&pdev->dev);
403 pdata->release_hardware_mutex(pld); 488 pdata->release_hardware_mutex(pld);
404 489