0001
0002
0003
0004
0005
0006
0007 #include <linux/hwmon.h>
0008 #include <linux/units.h>
0009
0010 #include <ufs/ufshcd.h>
0011 #include "ufshcd-priv.h"
0012
0013 struct ufs_hwmon_data {
0014 struct ufs_hba *hba;
0015 u8 mask;
0016 };
0017
0018 static int ufs_read_temp_enable(struct ufs_hba *hba, u8 mask, long *val)
0019 {
0020 u32 ee_mask;
0021 int err;
0022
0023 err = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, QUERY_ATTR_IDN_EE_CONTROL, 0, 0,
0024 &ee_mask);
0025 if (err)
0026 return err;
0027
0028 *val = (mask & ee_mask & MASK_EE_TOO_HIGH_TEMP) || (mask & ee_mask & MASK_EE_TOO_LOW_TEMP);
0029
0030 return 0;
0031 }
0032
0033 static int ufs_get_temp(struct ufs_hba *hba, enum attr_idn idn, long *val)
0034 {
0035 u32 value;
0036 int err;
0037
0038 err = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, idn, 0, 0, &value);
0039 if (err)
0040 return err;
0041
0042 if (value == 0)
0043 return -ENODATA;
0044
0045 *val = ((long)value - 80) * MILLIDEGREE_PER_DEGREE;
0046
0047 return 0;
0048 }
0049
0050 static int ufs_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
0051 long *val)
0052 {
0053 struct ufs_hwmon_data *data = dev_get_drvdata(dev);
0054 struct ufs_hba *hba = data->hba;
0055 int err;
0056
0057 down(&hba->host_sem);
0058
0059 if (!ufshcd_is_user_access_allowed(hba)) {
0060 up(&hba->host_sem);
0061 return -EBUSY;
0062 }
0063
0064 ufshcd_rpm_get_sync(hba);
0065
0066 switch (attr) {
0067 case hwmon_temp_enable:
0068 err = ufs_read_temp_enable(hba, data->mask, val);
0069
0070 break;
0071 case hwmon_temp_crit:
0072 err = ufs_get_temp(hba, QUERY_ATTR_IDN_HIGH_TEMP_BOUND, val);
0073
0074 break;
0075 case hwmon_temp_lcrit:
0076 err = ufs_get_temp(hba, QUERY_ATTR_IDN_LOW_TEMP_BOUND, val);
0077
0078 break;
0079 case hwmon_temp_input:
0080 err = ufs_get_temp(hba, QUERY_ATTR_IDN_CASE_ROUGH_TEMP, val);
0081
0082 break;
0083 default:
0084 err = -EOPNOTSUPP;
0085
0086 break;
0087 }
0088
0089 ufshcd_rpm_put_sync(hba);
0090
0091 up(&hba->host_sem);
0092
0093 return err;
0094 }
0095
0096 static int ufs_hwmon_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
0097 long val)
0098 {
0099 struct ufs_hwmon_data *data = dev_get_drvdata(dev);
0100 struct ufs_hba *hba = data->hba;
0101 int err;
0102
0103 if (attr != hwmon_temp_enable)
0104 return -EINVAL;
0105
0106 if (val != 0 && val != 1)
0107 return -EINVAL;
0108
0109 down(&hba->host_sem);
0110
0111 if (!ufshcd_is_user_access_allowed(hba)) {
0112 up(&hba->host_sem);
0113 return -EBUSY;
0114 }
0115
0116 ufshcd_rpm_get_sync(hba);
0117
0118 if (val == 1)
0119 err = ufshcd_update_ee_usr_mask(hba, MASK_EE_URGENT_TEMP, 0);
0120 else
0121 err = ufshcd_update_ee_usr_mask(hba, 0, MASK_EE_URGENT_TEMP);
0122
0123 ufshcd_rpm_put_sync(hba);
0124
0125 up(&hba->host_sem);
0126
0127 return err;
0128 }
0129
0130 static umode_t ufs_hwmon_is_visible(const void *_data, enum hwmon_sensor_types type, u32 attr,
0131 int channel)
0132 {
0133 if (type != hwmon_temp)
0134 return 0;
0135
0136 switch (attr) {
0137 case hwmon_temp_enable:
0138 return 0644;
0139 case hwmon_temp_crit:
0140 case hwmon_temp_lcrit:
0141 case hwmon_temp_input:
0142 return 0444;
0143 default:
0144 break;
0145 }
0146 return 0;
0147 }
0148
0149 static const struct hwmon_channel_info *ufs_hwmon_info[] = {
0150 HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_LCRIT),
0151 NULL
0152 };
0153
0154 static const struct hwmon_ops ufs_hwmon_ops = {
0155 .is_visible = ufs_hwmon_is_visible,
0156 .read = ufs_hwmon_read,
0157 .write = ufs_hwmon_write,
0158 };
0159
0160 static const struct hwmon_chip_info ufs_hwmon_hba_info = {
0161 .ops = &ufs_hwmon_ops,
0162 .info = ufs_hwmon_info,
0163 };
0164
0165 void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask)
0166 {
0167 struct device *dev = hba->dev;
0168 struct ufs_hwmon_data *data;
0169 struct device *hwmon;
0170
0171 data = kzalloc(sizeof(*data), GFP_KERNEL);
0172 if (!data)
0173 return;
0174
0175 data->hba = hba;
0176 data->mask = mask;
0177
0178 hwmon = hwmon_device_register_with_info(dev, "ufs", data, &ufs_hwmon_hba_info, NULL);
0179 if (IS_ERR(hwmon)) {
0180 dev_warn(dev, "Failed to instantiate hwmon device\n");
0181 kfree(data);
0182 return;
0183 }
0184
0185 hba->hwmon_device = hwmon;
0186 }
0187
0188 void ufs_hwmon_remove(struct ufs_hba *hba)
0189 {
0190 struct ufs_hwmon_data *data;
0191
0192 if (!hba->hwmon_device)
0193 return;
0194
0195 data = dev_get_drvdata(hba->hwmon_device);
0196 hwmon_device_unregister(hba->hwmon_device);
0197 hba->hwmon_device = NULL;
0198 kfree(data);
0199 }
0200
0201 void ufs_hwmon_notify_event(struct ufs_hba *hba, u8 ee_mask)
0202 {
0203 if (!hba->hwmon_device)
0204 return;
0205
0206 if (ee_mask & MASK_EE_TOO_HIGH_TEMP)
0207 hwmon_notify_event(hba->hwmon_device, hwmon_temp, hwmon_temp_max_alarm, 0);
0208
0209 if (ee_mask & MASK_EE_TOO_LOW_TEMP)
0210 hwmon_notify_event(hba->hwmon_device, hwmon_temp, hwmon_temp_min_alarm, 0);
0211 }