1603aed8fSIlpo Järvinen // SPDX-License-Identifier: GPL-2.0 2603aed8fSIlpo Järvinen /* 3603aed8fSIlpo Järvinen * Intel MAX 10 Board Management Controller chip - common code 4603aed8fSIlpo Järvinen * 5603aed8fSIlpo Järvinen * Copyright (C) 2018-2020 Intel Corporation. All rights reserved. 6603aed8fSIlpo Järvinen */ 7603aed8fSIlpo Järvinen 8603aed8fSIlpo Järvinen #include <linux/bitfield.h> 9603aed8fSIlpo Järvinen #include <linux/device.h> 10603aed8fSIlpo Järvinen #include <linux/dev_printk.h> 11603aed8fSIlpo Järvinen #include <linux/mfd/core.h> 12603aed8fSIlpo Järvinen #include <linux/mfd/intel-m10-bmc.h> 13603aed8fSIlpo Järvinen #include <linux/module.h> 14603aed8fSIlpo Järvinen 15603aed8fSIlpo Järvinen static ssize_t bmc_version_show(struct device *dev, 16603aed8fSIlpo Järvinen struct device_attribute *attr, char *buf) 17603aed8fSIlpo Järvinen { 18603aed8fSIlpo Järvinen struct intel_m10bmc *ddata = dev_get_drvdata(dev); 19603aed8fSIlpo Järvinen unsigned int val; 20603aed8fSIlpo Järvinen int ret; 21603aed8fSIlpo Järvinen 22*6052a005SIlpo Järvinen ret = m10bmc_sys_read(ddata, ddata->info->csr_map->build_version, &val); 23603aed8fSIlpo Järvinen if (ret) 24603aed8fSIlpo Järvinen return ret; 25603aed8fSIlpo Järvinen 26603aed8fSIlpo Järvinen return sprintf(buf, "0x%x\n", val); 27603aed8fSIlpo Järvinen } 28603aed8fSIlpo Järvinen static DEVICE_ATTR_RO(bmc_version); 29603aed8fSIlpo Järvinen 30603aed8fSIlpo Järvinen static ssize_t bmcfw_version_show(struct device *dev, 31603aed8fSIlpo Järvinen struct device_attribute *attr, char *buf) 32603aed8fSIlpo Järvinen { 33603aed8fSIlpo Järvinen struct intel_m10bmc *ddata = dev_get_drvdata(dev); 34603aed8fSIlpo Järvinen unsigned int val; 35603aed8fSIlpo Järvinen int ret; 36603aed8fSIlpo Järvinen 37*6052a005SIlpo Järvinen ret = m10bmc_sys_read(ddata, ddata->info->csr_map->fw_version, &val); 38603aed8fSIlpo Järvinen if (ret) 39603aed8fSIlpo Järvinen return ret; 40603aed8fSIlpo Järvinen 41603aed8fSIlpo Järvinen return sprintf(buf, "0x%x\n", val); 42603aed8fSIlpo Järvinen } 43603aed8fSIlpo Järvinen static DEVICE_ATTR_RO(bmcfw_version); 44603aed8fSIlpo Järvinen 45603aed8fSIlpo Järvinen static ssize_t mac_address_show(struct device *dev, 46603aed8fSIlpo Järvinen struct device_attribute *attr, char *buf) 47603aed8fSIlpo Järvinen { 48603aed8fSIlpo Järvinen struct intel_m10bmc *ddata = dev_get_drvdata(dev); 49603aed8fSIlpo Järvinen unsigned int macaddr_low, macaddr_high; 50603aed8fSIlpo Järvinen int ret; 51603aed8fSIlpo Järvinen 52*6052a005SIlpo Järvinen ret = m10bmc_sys_read(ddata, ddata->info->csr_map->mac_low, &macaddr_low); 53603aed8fSIlpo Järvinen if (ret) 54603aed8fSIlpo Järvinen return ret; 55603aed8fSIlpo Järvinen 56*6052a005SIlpo Järvinen ret = m10bmc_sys_read(ddata, ddata->info->csr_map->mac_high, &macaddr_high); 57603aed8fSIlpo Järvinen if (ret) 58603aed8fSIlpo Järvinen return ret; 59603aed8fSIlpo Järvinen 60603aed8fSIlpo Järvinen return sysfs_emit(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", 61603aed8fSIlpo Järvinen (u8)FIELD_GET(M10BMC_MAC_BYTE1, macaddr_low), 62603aed8fSIlpo Järvinen (u8)FIELD_GET(M10BMC_MAC_BYTE2, macaddr_low), 63603aed8fSIlpo Järvinen (u8)FIELD_GET(M10BMC_MAC_BYTE3, macaddr_low), 64603aed8fSIlpo Järvinen (u8)FIELD_GET(M10BMC_MAC_BYTE4, macaddr_low), 65603aed8fSIlpo Järvinen (u8)FIELD_GET(M10BMC_MAC_BYTE5, macaddr_high), 66603aed8fSIlpo Järvinen (u8)FIELD_GET(M10BMC_MAC_BYTE6, macaddr_high)); 67603aed8fSIlpo Järvinen } 68603aed8fSIlpo Järvinen static DEVICE_ATTR_RO(mac_address); 69603aed8fSIlpo Järvinen 70603aed8fSIlpo Järvinen static ssize_t mac_count_show(struct device *dev, 71603aed8fSIlpo Järvinen struct device_attribute *attr, char *buf) 72603aed8fSIlpo Järvinen { 73603aed8fSIlpo Järvinen struct intel_m10bmc *ddata = dev_get_drvdata(dev); 74603aed8fSIlpo Järvinen unsigned int macaddr_high; 75603aed8fSIlpo Järvinen int ret; 76603aed8fSIlpo Järvinen 77*6052a005SIlpo Järvinen ret = m10bmc_sys_read(ddata, ddata->info->csr_map->mac_high, &macaddr_high); 78603aed8fSIlpo Järvinen if (ret) 79603aed8fSIlpo Järvinen return ret; 80603aed8fSIlpo Järvinen 81603aed8fSIlpo Järvinen return sysfs_emit(buf, "%u\n", (u8)FIELD_GET(M10BMC_MAC_COUNT, macaddr_high)); 82603aed8fSIlpo Järvinen } 83603aed8fSIlpo Järvinen static DEVICE_ATTR_RO(mac_count); 84603aed8fSIlpo Järvinen 85603aed8fSIlpo Järvinen static struct attribute *m10bmc_attrs[] = { 86603aed8fSIlpo Järvinen &dev_attr_bmc_version.attr, 87603aed8fSIlpo Järvinen &dev_attr_bmcfw_version.attr, 88603aed8fSIlpo Järvinen &dev_attr_mac_address.attr, 89603aed8fSIlpo Järvinen &dev_attr_mac_count.attr, 90603aed8fSIlpo Järvinen NULL, 91603aed8fSIlpo Järvinen }; 92603aed8fSIlpo Järvinen 93603aed8fSIlpo Järvinen static const struct attribute_group m10bmc_group = { 94603aed8fSIlpo Järvinen .attrs = m10bmc_attrs, 95603aed8fSIlpo Järvinen }; 96603aed8fSIlpo Järvinen 97603aed8fSIlpo Järvinen const struct attribute_group *m10bmc_dev_groups[] = { 98603aed8fSIlpo Järvinen &m10bmc_group, 99603aed8fSIlpo Järvinen NULL, 100603aed8fSIlpo Järvinen }; 101603aed8fSIlpo Järvinen EXPORT_SYMBOL_GPL(m10bmc_dev_groups); 102603aed8fSIlpo Järvinen 103603aed8fSIlpo Järvinen int m10bmc_dev_init(struct intel_m10bmc *m10bmc, const struct intel_m10bmc_platform_info *info) 104603aed8fSIlpo Järvinen { 105603aed8fSIlpo Järvinen int ret; 106603aed8fSIlpo Järvinen 107603aed8fSIlpo Järvinen m10bmc->info = info; 108603aed8fSIlpo Järvinen dev_set_drvdata(m10bmc->dev, m10bmc); 109603aed8fSIlpo Järvinen 110603aed8fSIlpo Järvinen ret = devm_mfd_add_devices(m10bmc->dev, PLATFORM_DEVID_AUTO, 111603aed8fSIlpo Järvinen info->cells, info->n_cells, 112603aed8fSIlpo Järvinen NULL, 0, NULL); 113603aed8fSIlpo Järvinen if (ret) 114603aed8fSIlpo Järvinen dev_err(m10bmc->dev, "Failed to register sub-devices: %d\n", ret); 115603aed8fSIlpo Järvinen 116603aed8fSIlpo Järvinen return ret; 117603aed8fSIlpo Järvinen } 118603aed8fSIlpo Järvinen EXPORT_SYMBOL_GPL(m10bmc_dev_init); 119603aed8fSIlpo Järvinen 120603aed8fSIlpo Järvinen MODULE_DESCRIPTION("Intel MAX 10 BMC core driver"); 121603aed8fSIlpo Järvinen MODULE_AUTHOR("Intel Corporation"); 122603aed8fSIlpo Järvinen MODULE_LICENSE("GPL v2"); 123