1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * i2c-smbus.c - SMBus extensions to the I2C protocol 4 * 5 * Copyright (C) 2008 David Brownell 6 * Copyright (C) 2010-2019 Jean Delvare <jdelvare@suse.de> 7 */ 8 9 #include <linux/device.h> 10 #include <linux/dmi.h> 11 #include <linux/i2c.h> 12 #include <linux/i2c-smbus.h> 13 #include <linux/interrupt.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/of_irq.h> 17 #include <linux/slab.h> 18 #include <linux/workqueue.h> 19 20 struct i2c_smbus_alert { 21 struct work_struct alert; 22 struct i2c_client *ara; /* Alert response address */ 23 }; 24 25 struct alert_data { 26 unsigned short addr; 27 enum i2c_alert_protocol type; 28 unsigned int data; 29 }; 30 31 /* If this is the alerting device, notify its driver */ 32 static int smbus_do_alert(struct device *dev, void *addrp) 33 { 34 struct i2c_client *client = i2c_verify_client(dev); 35 struct alert_data *data = addrp; 36 struct i2c_driver *driver; 37 38 if (!client || client->addr != data->addr) 39 return 0; 40 if (client->flags & I2C_CLIENT_TEN) 41 return 0; 42 43 /* 44 * Drivers should either disable alerts, or provide at least 45 * a minimal handler. Lock so the driver won't change. 46 */ 47 device_lock(dev); 48 if (client->dev.driver) { 49 driver = to_i2c_driver(client->dev.driver); 50 if (driver->alert) 51 driver->alert(client, data->type, data->data); 52 else 53 dev_warn(&client->dev, "no driver alert()!\n"); 54 } else 55 dev_dbg(&client->dev, "alert with no driver\n"); 56 device_unlock(dev); 57 58 /* Stop iterating after we find the device */ 59 return -EBUSY; 60 } 61 62 /* 63 * The alert IRQ handler needs to hand work off to a task which can issue 64 * SMBus calls, because those sleeping calls can't be made in IRQ context. 65 */ 66 static irqreturn_t smbus_alert(int irq, void *d) 67 { 68 struct i2c_smbus_alert *alert = d; 69 struct i2c_client *ara; 70 71 ara = alert->ara; 72 73 for (;;) { 74 s32 status; 75 struct alert_data data; 76 77 /* 78 * Devices with pending alerts reply in address order, low 79 * to high, because of slave transmit arbitration. After 80 * responding, an SMBus device stops asserting SMBALERT#. 81 * 82 * Note that SMBus 2.0 reserves 10-bit addresses for future 83 * use. We neither handle them, nor try to use PEC here. 84 */ 85 status = i2c_smbus_read_byte(ara); 86 if (status < 0) 87 break; 88 89 data.data = status & 1; 90 data.addr = status >> 1; 91 data.type = I2C_PROTOCOL_SMBUS_ALERT; 92 93 dev_dbg(&ara->dev, "SMBALERT# from dev 0x%02x, flag %d\n", 94 data.addr, data.data); 95 96 /* Notify driver for the device which issued the alert */ 97 device_for_each_child(&ara->adapter->dev, &data, 98 smbus_do_alert); 99 } 100 101 return IRQ_HANDLED; 102 } 103 104 static void smbalert_work(struct work_struct *work) 105 { 106 struct i2c_smbus_alert *alert; 107 108 alert = container_of(work, struct i2c_smbus_alert, alert); 109 110 smbus_alert(0, alert); 111 112 } 113 114 /* Setup SMBALERT# infrastructure */ 115 static int smbalert_probe(struct i2c_client *ara, 116 const struct i2c_device_id *id) 117 { 118 struct i2c_smbus_alert_setup *setup = dev_get_platdata(&ara->dev); 119 struct i2c_smbus_alert *alert; 120 struct i2c_adapter *adapter = ara->adapter; 121 int res, irq; 122 123 alert = devm_kzalloc(&ara->dev, sizeof(struct i2c_smbus_alert), 124 GFP_KERNEL); 125 if (!alert) 126 return -ENOMEM; 127 128 if (setup) { 129 irq = setup->irq; 130 } else { 131 irq = of_irq_get_byname(adapter->dev.of_node, "smbus_alert"); 132 if (irq <= 0) 133 return irq; 134 } 135 136 INIT_WORK(&alert->alert, smbalert_work); 137 alert->ara = ara; 138 139 if (irq > 0) { 140 res = devm_request_threaded_irq(&ara->dev, irq, 141 NULL, smbus_alert, 142 IRQF_SHARED | IRQF_ONESHOT, 143 "smbus_alert", alert); 144 if (res) 145 return res; 146 } 147 148 i2c_set_clientdata(ara, alert); 149 dev_info(&adapter->dev, "supports SMBALERT#\n"); 150 151 return 0; 152 } 153 154 /* IRQ and memory resources are managed so they are freed automatically */ 155 static int smbalert_remove(struct i2c_client *ara) 156 { 157 struct i2c_smbus_alert *alert = i2c_get_clientdata(ara); 158 159 cancel_work_sync(&alert->alert); 160 return 0; 161 } 162 163 static const struct i2c_device_id smbalert_ids[] = { 164 { "smbus_alert", 0 }, 165 { /* LIST END */ } 166 }; 167 MODULE_DEVICE_TABLE(i2c, smbalert_ids); 168 169 static struct i2c_driver smbalert_driver = { 170 .driver = { 171 .name = "smbus_alert", 172 }, 173 .probe = smbalert_probe, 174 .remove = smbalert_remove, 175 .id_table = smbalert_ids, 176 }; 177 178 /** 179 * i2c_handle_smbus_alert - Handle an SMBus alert 180 * @ara: the ARA client on the relevant adapter 181 * Context: can't sleep 182 * 183 * Helper function to be called from an I2C bus driver's interrupt 184 * handler. It will schedule the alert work, in turn calling the 185 * corresponding I2C device driver's alert function. 186 * 187 * It is assumed that ara is a valid i2c client previously returned by 188 * i2c_new_smbus_alert_device(). 189 */ 190 int i2c_handle_smbus_alert(struct i2c_client *ara) 191 { 192 struct i2c_smbus_alert *alert = i2c_get_clientdata(ara); 193 194 return schedule_work(&alert->alert); 195 } 196 EXPORT_SYMBOL_GPL(i2c_handle_smbus_alert); 197 198 module_i2c_driver(smbalert_driver); 199 200 /* 201 * SPD is not part of SMBus but we include it here for convenience as the 202 * target systems are the same. 203 * Restrictions to automatic SPD instantiation: 204 * - Only works if all filled slots have the same memory type 205 * - Only works for DDR2, DDR3 and DDR4 for now 206 * - Only works on systems with 1 to 4 memory slots 207 */ 208 #if IS_ENABLED(CONFIG_DMI) 209 void i2c_register_spd(struct i2c_adapter *adap) 210 { 211 int n, slot_count = 0, dimm_count = 0; 212 u16 handle; 213 u8 common_mem_type = 0x0, mem_type; 214 u64 mem_size; 215 const char *name; 216 217 while ((handle = dmi_memdev_handle(slot_count)) != 0xffff) { 218 slot_count++; 219 220 /* Skip empty slots */ 221 mem_size = dmi_memdev_size(handle); 222 if (!mem_size) 223 continue; 224 225 /* Skip undefined memory type */ 226 mem_type = dmi_memdev_type(handle); 227 if (mem_type <= 0x02) /* Invalid, Other, Unknown */ 228 continue; 229 230 if (!common_mem_type) { 231 /* First filled slot */ 232 common_mem_type = mem_type; 233 } else { 234 /* Check that all filled slots have the same type */ 235 if (mem_type != common_mem_type) { 236 dev_warn(&adap->dev, 237 "Different memory types mixed, not instantiating SPD\n"); 238 return; 239 } 240 } 241 dimm_count++; 242 } 243 244 /* No useful DMI data, bail out */ 245 if (!dimm_count) 246 return; 247 248 dev_info(&adap->dev, "%d/%d memory slots populated (from DMI)\n", 249 dimm_count, slot_count); 250 251 if (slot_count > 4) { 252 dev_warn(&adap->dev, 253 "Systems with more than 4 memory slots not supported yet, not instantiating SPD\n"); 254 return; 255 } 256 257 switch (common_mem_type) { 258 case 0x13: /* DDR2 */ 259 case 0x18: /* DDR3 */ 260 case 0x1C: /* LPDDR2 */ 261 case 0x1D: /* LPDDR3 */ 262 name = "spd"; 263 break; 264 case 0x1A: /* DDR4 */ 265 case 0x1E: /* LPDDR4 */ 266 name = "ee1004"; 267 break; 268 default: 269 dev_info(&adap->dev, 270 "Memory type 0x%02x not supported yet, not instantiating SPD\n", 271 common_mem_type); 272 return; 273 } 274 275 /* 276 * We don't know in which slots the memory modules are. We could 277 * try to guess from the slot names, but that would be rather complex 278 * and unreliable, so better probe all possible addresses until we 279 * have found all memory modules. 280 */ 281 for (n = 0; n < slot_count && dimm_count; n++) { 282 struct i2c_board_info info; 283 unsigned short addr_list[2]; 284 285 memset(&info, 0, sizeof(struct i2c_board_info)); 286 strlcpy(info.type, name, I2C_NAME_SIZE); 287 addr_list[0] = 0x50 + n; 288 addr_list[1] = I2C_CLIENT_END; 289 290 if (!IS_ERR(i2c_new_scanned_device(adap, &info, addr_list, NULL))) { 291 dev_info(&adap->dev, 292 "Successfully instantiated SPD at 0x%hx\n", 293 addr_list[0]); 294 dimm_count--; 295 } 296 } 297 } 298 EXPORT_SYMBOL_GPL(i2c_register_spd); 299 #endif 300 301 MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>"); 302 MODULE_DESCRIPTION("SMBus protocol extensions support"); 303 MODULE_LICENSE("GPL"); 304