1*603aed8fSIlpo Järvinen // SPDX-License-Identifier: GPL-2.0 2*603aed8fSIlpo Järvinen /* 3*603aed8fSIlpo Järvinen * Intel MAX 10 Board Management Controller chip - common code 4*603aed8fSIlpo Järvinen * 5*603aed8fSIlpo Järvinen * Copyright (C) 2018-2020 Intel Corporation. All rights reserved. 6*603aed8fSIlpo Järvinen */ 7*603aed8fSIlpo Järvinen 8*603aed8fSIlpo Järvinen #include <linux/bitfield.h> 9*603aed8fSIlpo Järvinen #include <linux/device.h> 10*603aed8fSIlpo Järvinen #include <linux/dev_printk.h> 11*603aed8fSIlpo Järvinen #include <linux/mfd/core.h> 12*603aed8fSIlpo Järvinen #include <linux/mfd/intel-m10-bmc.h> 13*603aed8fSIlpo Järvinen #include <linux/module.h> 14*603aed8fSIlpo Järvinen 15*603aed8fSIlpo Järvinen static ssize_t bmc_version_show(struct device *dev, 16*603aed8fSIlpo Järvinen struct device_attribute *attr, char *buf) 17*603aed8fSIlpo Järvinen { 18*603aed8fSIlpo Järvinen struct intel_m10bmc *ddata = dev_get_drvdata(dev); 19*603aed8fSIlpo Järvinen unsigned int val; 20*603aed8fSIlpo Järvinen int ret; 21*603aed8fSIlpo Järvinen 22*603aed8fSIlpo Järvinen ret = m10bmc_sys_read(ddata, M10BMC_BUILD_VER, &val); 23*603aed8fSIlpo Järvinen if (ret) 24*603aed8fSIlpo Järvinen return ret; 25*603aed8fSIlpo Järvinen 26*603aed8fSIlpo Järvinen return sprintf(buf, "0x%x\n", val); 27*603aed8fSIlpo Järvinen } 28*603aed8fSIlpo Järvinen static DEVICE_ATTR_RO(bmc_version); 29*603aed8fSIlpo Järvinen 30*603aed8fSIlpo Järvinen static ssize_t bmcfw_version_show(struct device *dev, 31*603aed8fSIlpo Järvinen struct device_attribute *attr, char *buf) 32*603aed8fSIlpo Järvinen { 33*603aed8fSIlpo Järvinen struct intel_m10bmc *ddata = dev_get_drvdata(dev); 34*603aed8fSIlpo Järvinen unsigned int val; 35*603aed8fSIlpo Järvinen int ret; 36*603aed8fSIlpo Järvinen 37*603aed8fSIlpo Järvinen ret = m10bmc_sys_read(ddata, NIOS2_FW_VERSION, &val); 38*603aed8fSIlpo Järvinen if (ret) 39*603aed8fSIlpo Järvinen return ret; 40*603aed8fSIlpo Järvinen 41*603aed8fSIlpo Järvinen return sprintf(buf, "0x%x\n", val); 42*603aed8fSIlpo Järvinen } 43*603aed8fSIlpo Järvinen static DEVICE_ATTR_RO(bmcfw_version); 44*603aed8fSIlpo Järvinen 45*603aed8fSIlpo Järvinen static ssize_t mac_address_show(struct device *dev, 46*603aed8fSIlpo Järvinen struct device_attribute *attr, char *buf) 47*603aed8fSIlpo Järvinen { 48*603aed8fSIlpo Järvinen struct intel_m10bmc *ddata = dev_get_drvdata(dev); 49*603aed8fSIlpo Järvinen unsigned int macaddr_low, macaddr_high; 50*603aed8fSIlpo Järvinen int ret; 51*603aed8fSIlpo Järvinen 52*603aed8fSIlpo Järvinen ret = m10bmc_sys_read(ddata, M10BMC_MAC_LOW, &macaddr_low); 53*603aed8fSIlpo Järvinen if (ret) 54*603aed8fSIlpo Järvinen return ret; 55*603aed8fSIlpo Järvinen 56*603aed8fSIlpo Järvinen ret = m10bmc_sys_read(ddata, M10BMC_MAC_HIGH, &macaddr_high); 57*603aed8fSIlpo Järvinen if (ret) 58*603aed8fSIlpo Järvinen return ret; 59*603aed8fSIlpo Järvinen 60*603aed8fSIlpo Järvinen return sysfs_emit(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", 61*603aed8fSIlpo Järvinen (u8)FIELD_GET(M10BMC_MAC_BYTE1, macaddr_low), 62*603aed8fSIlpo Järvinen (u8)FIELD_GET(M10BMC_MAC_BYTE2, macaddr_low), 63*603aed8fSIlpo Järvinen (u8)FIELD_GET(M10BMC_MAC_BYTE3, macaddr_low), 64*603aed8fSIlpo Järvinen (u8)FIELD_GET(M10BMC_MAC_BYTE4, macaddr_low), 65*603aed8fSIlpo Järvinen (u8)FIELD_GET(M10BMC_MAC_BYTE5, macaddr_high), 66*603aed8fSIlpo Järvinen (u8)FIELD_GET(M10BMC_MAC_BYTE6, macaddr_high)); 67*603aed8fSIlpo Järvinen } 68*603aed8fSIlpo Järvinen static DEVICE_ATTR_RO(mac_address); 69*603aed8fSIlpo Järvinen 70*603aed8fSIlpo Järvinen static ssize_t mac_count_show(struct device *dev, 71*603aed8fSIlpo Järvinen struct device_attribute *attr, char *buf) 72*603aed8fSIlpo Järvinen { 73*603aed8fSIlpo Järvinen struct intel_m10bmc *ddata = dev_get_drvdata(dev); 74*603aed8fSIlpo Järvinen unsigned int macaddr_high; 75*603aed8fSIlpo Järvinen int ret; 76*603aed8fSIlpo Järvinen 77*603aed8fSIlpo Järvinen ret = m10bmc_sys_read(ddata, M10BMC_MAC_HIGH, &macaddr_high); 78*603aed8fSIlpo Järvinen if (ret) 79*603aed8fSIlpo Järvinen return ret; 80*603aed8fSIlpo Järvinen 81*603aed8fSIlpo Järvinen return sysfs_emit(buf, "%u\n", (u8)FIELD_GET(M10BMC_MAC_COUNT, macaddr_high)); 82*603aed8fSIlpo Järvinen } 83*603aed8fSIlpo Järvinen static DEVICE_ATTR_RO(mac_count); 84*603aed8fSIlpo Järvinen 85*603aed8fSIlpo Järvinen static struct attribute *m10bmc_attrs[] = { 86*603aed8fSIlpo Järvinen &dev_attr_bmc_version.attr, 87*603aed8fSIlpo Järvinen &dev_attr_bmcfw_version.attr, 88*603aed8fSIlpo Järvinen &dev_attr_mac_address.attr, 89*603aed8fSIlpo Järvinen &dev_attr_mac_count.attr, 90*603aed8fSIlpo Järvinen NULL, 91*603aed8fSIlpo Järvinen }; 92*603aed8fSIlpo Järvinen 93*603aed8fSIlpo Järvinen static const struct attribute_group m10bmc_group = { 94*603aed8fSIlpo Järvinen .attrs = m10bmc_attrs, 95*603aed8fSIlpo Järvinen }; 96*603aed8fSIlpo Järvinen 97*603aed8fSIlpo Järvinen const struct attribute_group *m10bmc_dev_groups[] = { 98*603aed8fSIlpo Järvinen &m10bmc_group, 99*603aed8fSIlpo Järvinen NULL, 100*603aed8fSIlpo Järvinen }; 101*603aed8fSIlpo Järvinen EXPORT_SYMBOL_GPL(m10bmc_dev_groups); 102*603aed8fSIlpo Järvinen 103*603aed8fSIlpo Järvinen int m10bmc_dev_init(struct intel_m10bmc *m10bmc, const struct intel_m10bmc_platform_info *info) 104*603aed8fSIlpo Järvinen { 105*603aed8fSIlpo Järvinen int ret; 106*603aed8fSIlpo Järvinen 107*603aed8fSIlpo Järvinen m10bmc->info = info; 108*603aed8fSIlpo Järvinen dev_set_drvdata(m10bmc->dev, m10bmc); 109*603aed8fSIlpo Järvinen 110*603aed8fSIlpo Järvinen ret = devm_mfd_add_devices(m10bmc->dev, PLATFORM_DEVID_AUTO, 111*603aed8fSIlpo Järvinen info->cells, info->n_cells, 112*603aed8fSIlpo Järvinen NULL, 0, NULL); 113*603aed8fSIlpo Järvinen if (ret) 114*603aed8fSIlpo Järvinen dev_err(m10bmc->dev, "Failed to register sub-devices: %d\n", ret); 115*603aed8fSIlpo Järvinen 116*603aed8fSIlpo Järvinen return ret; 117*603aed8fSIlpo Järvinen } 118*603aed8fSIlpo Järvinen EXPORT_SYMBOL_GPL(m10bmc_dev_init); 119*603aed8fSIlpo Järvinen 120*603aed8fSIlpo Järvinen MODULE_DESCRIPTION("Intel MAX 10 BMC core driver"); 121*603aed8fSIlpo Järvinen MODULE_AUTHOR("Intel Corporation"); 122*603aed8fSIlpo Järvinen MODULE_LICENSE("GPL v2"); 123