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 15*c452e3bdSIlpo Järvinen int m10bmc_sys_update_bits(struct intel_m10bmc *m10bmc, unsigned int offset, 16*c452e3bdSIlpo Järvinen unsigned int msk, unsigned int val) 17*c452e3bdSIlpo Järvinen { 18*c452e3bdSIlpo Järvinen const struct m10bmc_csr_map *csr_map = m10bmc->info->csr_map; 19*c452e3bdSIlpo Järvinen 20*c452e3bdSIlpo Järvinen return regmap_update_bits(m10bmc->regmap, csr_map->base + offset, msk, val); 21*c452e3bdSIlpo Järvinen } 22*c452e3bdSIlpo Järvinen EXPORT_SYMBOL_NS_GPL(m10bmc_sys_update_bits, INTEL_M10_BMC_CORE); 23*c452e3bdSIlpo Järvinen 24603aed8fSIlpo Järvinen static ssize_t bmc_version_show(struct device *dev, 25603aed8fSIlpo Järvinen struct device_attribute *attr, char *buf) 26603aed8fSIlpo Järvinen { 27603aed8fSIlpo Järvinen struct intel_m10bmc *ddata = dev_get_drvdata(dev); 28603aed8fSIlpo Järvinen unsigned int val; 29603aed8fSIlpo Järvinen int ret; 30603aed8fSIlpo Järvinen 316052a005SIlpo Järvinen ret = m10bmc_sys_read(ddata, ddata->info->csr_map->build_version, &val); 32603aed8fSIlpo Järvinen if (ret) 33603aed8fSIlpo Järvinen return ret; 34603aed8fSIlpo Järvinen 35603aed8fSIlpo Järvinen return sprintf(buf, "0x%x\n", val); 36603aed8fSIlpo Järvinen } 37603aed8fSIlpo Järvinen static DEVICE_ATTR_RO(bmc_version); 38603aed8fSIlpo Järvinen 39603aed8fSIlpo Järvinen static ssize_t bmcfw_version_show(struct device *dev, 40603aed8fSIlpo Järvinen struct device_attribute *attr, char *buf) 41603aed8fSIlpo Järvinen { 42603aed8fSIlpo Järvinen struct intel_m10bmc *ddata = dev_get_drvdata(dev); 43603aed8fSIlpo Järvinen unsigned int val; 44603aed8fSIlpo Järvinen int ret; 45603aed8fSIlpo Järvinen 466052a005SIlpo Järvinen ret = m10bmc_sys_read(ddata, ddata->info->csr_map->fw_version, &val); 47603aed8fSIlpo Järvinen if (ret) 48603aed8fSIlpo Järvinen return ret; 49603aed8fSIlpo Järvinen 50603aed8fSIlpo Järvinen return sprintf(buf, "0x%x\n", val); 51603aed8fSIlpo Järvinen } 52603aed8fSIlpo Järvinen static DEVICE_ATTR_RO(bmcfw_version); 53603aed8fSIlpo Järvinen 54603aed8fSIlpo Järvinen static ssize_t mac_address_show(struct device *dev, 55603aed8fSIlpo Järvinen struct device_attribute *attr, char *buf) 56603aed8fSIlpo Järvinen { 57603aed8fSIlpo Järvinen struct intel_m10bmc *ddata = dev_get_drvdata(dev); 58603aed8fSIlpo Järvinen unsigned int macaddr_low, macaddr_high; 59603aed8fSIlpo Järvinen int ret; 60603aed8fSIlpo Järvinen 616052a005SIlpo Järvinen ret = m10bmc_sys_read(ddata, ddata->info->csr_map->mac_low, &macaddr_low); 62603aed8fSIlpo Järvinen if (ret) 63603aed8fSIlpo Järvinen return ret; 64603aed8fSIlpo Järvinen 656052a005SIlpo Järvinen ret = m10bmc_sys_read(ddata, ddata->info->csr_map->mac_high, &macaddr_high); 66603aed8fSIlpo Järvinen if (ret) 67603aed8fSIlpo Järvinen return ret; 68603aed8fSIlpo Järvinen 69603aed8fSIlpo Järvinen return sysfs_emit(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", 70bcababfcSIlpo Järvinen (u8)FIELD_GET(M10BMC_N3000_MAC_BYTE1, macaddr_low), 71bcababfcSIlpo Järvinen (u8)FIELD_GET(M10BMC_N3000_MAC_BYTE2, macaddr_low), 72bcababfcSIlpo Järvinen (u8)FIELD_GET(M10BMC_N3000_MAC_BYTE3, macaddr_low), 73bcababfcSIlpo Järvinen (u8)FIELD_GET(M10BMC_N3000_MAC_BYTE4, macaddr_low), 74bcababfcSIlpo Järvinen (u8)FIELD_GET(M10BMC_N3000_MAC_BYTE5, macaddr_high), 75bcababfcSIlpo Järvinen (u8)FIELD_GET(M10BMC_N3000_MAC_BYTE6, macaddr_high)); 76603aed8fSIlpo Järvinen } 77603aed8fSIlpo Järvinen static DEVICE_ATTR_RO(mac_address); 78603aed8fSIlpo Järvinen 79603aed8fSIlpo Järvinen static ssize_t mac_count_show(struct device *dev, 80603aed8fSIlpo Järvinen struct device_attribute *attr, char *buf) 81603aed8fSIlpo Järvinen { 82603aed8fSIlpo Järvinen struct intel_m10bmc *ddata = dev_get_drvdata(dev); 83603aed8fSIlpo Järvinen unsigned int macaddr_high; 84603aed8fSIlpo Järvinen int ret; 85603aed8fSIlpo Järvinen 866052a005SIlpo Järvinen ret = m10bmc_sys_read(ddata, ddata->info->csr_map->mac_high, &macaddr_high); 87603aed8fSIlpo Järvinen if (ret) 88603aed8fSIlpo Järvinen return ret; 89603aed8fSIlpo Järvinen 90bcababfcSIlpo Järvinen return sysfs_emit(buf, "%u\n", (u8)FIELD_GET(M10BMC_N3000_MAC_COUNT, macaddr_high)); 91603aed8fSIlpo Järvinen } 92603aed8fSIlpo Järvinen static DEVICE_ATTR_RO(mac_count); 93603aed8fSIlpo Järvinen 94603aed8fSIlpo Järvinen static struct attribute *m10bmc_attrs[] = { 95603aed8fSIlpo Järvinen &dev_attr_bmc_version.attr, 96603aed8fSIlpo Järvinen &dev_attr_bmcfw_version.attr, 97603aed8fSIlpo Järvinen &dev_attr_mac_address.attr, 98603aed8fSIlpo Järvinen &dev_attr_mac_count.attr, 99603aed8fSIlpo Järvinen NULL, 100603aed8fSIlpo Järvinen }; 101603aed8fSIlpo Järvinen 102603aed8fSIlpo Järvinen static const struct attribute_group m10bmc_group = { 103603aed8fSIlpo Järvinen .attrs = m10bmc_attrs, 104603aed8fSIlpo Järvinen }; 105603aed8fSIlpo Järvinen 106603aed8fSIlpo Järvinen const struct attribute_group *m10bmc_dev_groups[] = { 107603aed8fSIlpo Järvinen &m10bmc_group, 108603aed8fSIlpo Järvinen NULL, 109603aed8fSIlpo Järvinen }; 110b3ecc7f3SIlpo Järvinen EXPORT_SYMBOL_NS_GPL(m10bmc_dev_groups, INTEL_M10_BMC_CORE); 111603aed8fSIlpo Järvinen 112603aed8fSIlpo Järvinen int m10bmc_dev_init(struct intel_m10bmc *m10bmc, const struct intel_m10bmc_platform_info *info) 113603aed8fSIlpo Järvinen { 114603aed8fSIlpo Järvinen int ret; 115603aed8fSIlpo Järvinen 116603aed8fSIlpo Järvinen m10bmc->info = info; 117603aed8fSIlpo Järvinen dev_set_drvdata(m10bmc->dev, m10bmc); 118603aed8fSIlpo Järvinen 119603aed8fSIlpo Järvinen ret = devm_mfd_add_devices(m10bmc->dev, PLATFORM_DEVID_AUTO, 120603aed8fSIlpo Järvinen info->cells, info->n_cells, 121603aed8fSIlpo Järvinen NULL, 0, NULL); 122603aed8fSIlpo Järvinen if (ret) 123603aed8fSIlpo Järvinen dev_err(m10bmc->dev, "Failed to register sub-devices: %d\n", ret); 124603aed8fSIlpo Järvinen 125603aed8fSIlpo Järvinen return ret; 126603aed8fSIlpo Järvinen } 127b3ecc7f3SIlpo Järvinen EXPORT_SYMBOL_NS_GPL(m10bmc_dev_init, INTEL_M10_BMC_CORE); 128603aed8fSIlpo Järvinen 129603aed8fSIlpo Järvinen MODULE_DESCRIPTION("Intel MAX 10 BMC core driver"); 130603aed8fSIlpo Järvinen MODULE_AUTHOR("Intel Corporation"); 131603aed8fSIlpo Järvinen MODULE_LICENSE("GPL v2"); 132