Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'amlogic-drivers' of https://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic into arm/drivers

soc: amlogic: updates for v5.5

Highlights
- socinfo: more SoC IDs
- firmware: misc secure-monitor cleanups

* tag 'amlogic-drivers' of https://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic:
soc: amlogic: meson-gx-socinfo: Fix S905D3 ID for VIM3L
soc: amlogic: meson-gx-socinfo: Add S905X3 ID for VIM3L
soc: amlogic: meson-gx-socinfo: Add A1 and A113L IDs
firmware: meson_sm: use %*ph to print small buffer
firmware: meson_sm: Rework driver as a proper platform driver
nvmem: meson-efuse: bindings: Add secure-monitor phandle
firmware: meson_sm: Mark chip struct as static const

Link: https://lore.kernel.org/r/7hftivs11f.fsf@baylibre.com
Signed-off-by: Olof Johansson <olof@lixom.net>

+105 -53
+6
Documentation/devicetree/bindings/nvmem/amlogic-efuse.txt
··· 4 4 - compatible: should be "amlogic,meson-gxbb-efuse" 5 5 - clocks: phandle to the efuse peripheral clock provided by the 6 6 clock controller. 7 + - secure-monitor: phandle to the secure-monitor node 7 8 8 9 = Data cells = 9 10 Are child nodes of eFuse, bindings of which as described in ··· 17 16 clocks = <&clkc CLKID_EFUSE>; 18 17 #address-cells = <1>; 19 18 #size-cells = <1>; 19 + secure-monitor = <&sm>; 20 20 21 21 sn: sn@14 { 22 22 reg = <0x14 0x10>; ··· 30 28 bid: bid@46 { 31 29 reg = <0x46 0x30>; 32 30 }; 31 + }; 32 + 33 + sm: secure-monitor { 34 + compatible = "amlogic,meson-gxbb-sm"; 33 35 }; 34 36 35 37 = Data consumers =
+66 -44
drivers/firmware/meson/meson_sm.c
··· 35 35 struct meson_sm_cmd cmd[]; 36 36 }; 37 37 38 - struct meson_sm_chip gxbb_chip = { 38 + static const struct meson_sm_chip gxbb_chip = { 39 39 .shmem_size = SZ_4K, 40 40 .cmd_shmem_in_base = 0x82000020, 41 41 .cmd_shmem_out_base = 0x82000021, ··· 53 53 void __iomem *sm_shmem_in_base; 54 54 void __iomem *sm_shmem_out_base; 55 55 }; 56 - 57 - static struct meson_sm_firmware fw; 58 56 59 57 static u32 meson_sm_get_cmd(const struct meson_sm_chip *chip, 60 58 unsigned int cmd_index) ··· 88 90 /** 89 91 * meson_sm_call - generic SMC32 call to the secure-monitor 90 92 * 93 + * @fw: Pointer to secure-monitor firmware 91 94 * @cmd_index: Index of the SMC32 function ID 92 95 * @ret: Returned value 93 96 * @arg0: SMC32 Argument 0 ··· 99 100 * 100 101 * Return: 0 on success, a negative value on error 101 102 */ 102 - int meson_sm_call(unsigned int cmd_index, u32 *ret, u32 arg0, 103 - u32 arg1, u32 arg2, u32 arg3, u32 arg4) 103 + int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index, 104 + u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4) 104 105 { 105 106 u32 cmd, lret; 106 107 107 - if (!fw.chip) 108 + if (!fw->chip) 108 109 return -ENOENT; 109 110 110 - cmd = meson_sm_get_cmd(fw.chip, cmd_index); 111 + cmd = meson_sm_get_cmd(fw->chip, cmd_index); 111 112 if (!cmd) 112 113 return -EINVAL; 113 114 ··· 123 124 /** 124 125 * meson_sm_call_read - retrieve data from secure-monitor 125 126 * 127 + * @fw: Pointer to secure-monitor firmware 126 128 * @buffer: Buffer to store the retrieved data 127 129 * @bsize: Size of the buffer 128 130 * @cmd_index: Index of the SMC32 function ID ··· 137 137 * When 0 is returned there is no guarantee about the amount of 138 138 * data read and bsize bytes are copied in buffer. 139 139 */ 140 - int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index, 141 - u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4) 140 + int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer, 141 + unsigned int bsize, unsigned int cmd_index, u32 arg0, 142 + u32 arg1, u32 arg2, u32 arg3, u32 arg4) 142 143 { 143 144 u32 size; 144 145 int ret; 145 146 146 - if (!fw.chip) 147 + if (!fw->chip) 147 148 return -ENOENT; 148 149 149 - if (!fw.chip->cmd_shmem_out_base) 150 + if (!fw->chip->cmd_shmem_out_base) 150 151 return -EINVAL; 151 152 152 - if (bsize > fw.chip->shmem_size) 153 + if (bsize > fw->chip->shmem_size) 153 154 return -EINVAL; 154 155 155 - if (meson_sm_call(cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0) 156 + if (meson_sm_call(fw, cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0) 156 157 return -EINVAL; 157 158 158 159 if (size > bsize) ··· 165 164 size = bsize; 166 165 167 166 if (buffer) 168 - memcpy(buffer, fw.sm_shmem_out_base, size); 167 + memcpy(buffer, fw->sm_shmem_out_base, size); 169 168 170 169 return ret; 171 170 } ··· 174 173 /** 175 174 * meson_sm_call_write - send data to secure-monitor 176 175 * 176 + * @fw: Pointer to secure-monitor firmware 177 177 * @buffer: Buffer containing data to send 178 178 * @size: Size of the data to send 179 179 * @cmd_index: Index of the SMC32 function ID ··· 186 184 * 187 185 * Return: size of sent data on success, a negative value on error 188 186 */ 189 - int meson_sm_call_write(void *buffer, unsigned int size, unsigned int cmd_index, 190 - u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4) 187 + int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer, 188 + unsigned int size, unsigned int cmd_index, u32 arg0, 189 + u32 arg1, u32 arg2, u32 arg3, u32 arg4) 191 190 { 192 191 u32 written; 193 192 194 - if (!fw.chip) 193 + if (!fw->chip) 195 194 return -ENOENT; 196 195 197 - if (size > fw.chip->shmem_size) 196 + if (size > fw->chip->shmem_size) 198 197 return -EINVAL; 199 198 200 - if (!fw.chip->cmd_shmem_in_base) 199 + if (!fw->chip->cmd_shmem_in_base) 201 200 return -EINVAL; 202 201 203 - memcpy(fw.sm_shmem_in_base, buffer, size); 202 + memcpy(fw->sm_shmem_in_base, buffer, size); 204 203 205 - if (meson_sm_call(cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0) 204 + if (meson_sm_call(fw, cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0) 206 205 return -EINVAL; 207 206 208 207 if (!written) ··· 213 210 } 214 211 EXPORT_SYMBOL(meson_sm_call_write); 215 212 213 + /** 214 + * meson_sm_get - get pointer to meson_sm_firmware structure. 215 + * 216 + * @sm_node: Pointer to the secure-monitor Device Tree node. 217 + * 218 + * Return: NULL is the secure-monitor device is not ready. 219 + */ 220 + struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node) 221 + { 222 + struct platform_device *pdev = of_find_device_by_node(sm_node); 223 + 224 + if (!pdev) 225 + return NULL; 226 + 227 + return platform_get_drvdata(pdev); 228 + } 229 + EXPORT_SYMBOL_GPL(meson_sm_get); 230 + 216 231 #define SM_CHIP_ID_LENGTH 119 217 232 #define SM_CHIP_ID_OFFSET 4 218 233 #define SM_CHIP_ID_SIZE 12 ··· 238 217 static ssize_t serial_show(struct device *dev, struct device_attribute *attr, 239 218 char *buf) 240 219 { 220 + struct platform_device *pdev = to_platform_device(dev); 221 + struct meson_sm_firmware *fw; 241 222 uint8_t *id_buf; 242 223 int ret; 224 + 225 + fw = platform_get_drvdata(pdev); 243 226 244 227 id_buf = kmalloc(SM_CHIP_ID_LENGTH, GFP_KERNEL); 245 228 if (!id_buf) 246 229 return -ENOMEM; 247 230 248 - ret = meson_sm_call_read(id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID, 231 + ret = meson_sm_call_read(fw, id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID, 249 232 0, 0, 0, 0, 0); 250 233 if (ret < 0) { 251 234 kfree(id_buf); 252 235 return ret; 253 236 } 254 237 255 - ret = sprintf(buf, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", 256 - id_buf[SM_CHIP_ID_OFFSET + 0], 257 - id_buf[SM_CHIP_ID_OFFSET + 1], 258 - id_buf[SM_CHIP_ID_OFFSET + 2], 259 - id_buf[SM_CHIP_ID_OFFSET + 3], 260 - id_buf[SM_CHIP_ID_OFFSET + 4], 261 - id_buf[SM_CHIP_ID_OFFSET + 5], 262 - id_buf[SM_CHIP_ID_OFFSET + 6], 263 - id_buf[SM_CHIP_ID_OFFSET + 7], 264 - id_buf[SM_CHIP_ID_OFFSET + 8], 265 - id_buf[SM_CHIP_ID_OFFSET + 9], 266 - id_buf[SM_CHIP_ID_OFFSET + 10], 267 - id_buf[SM_CHIP_ID_OFFSET + 11]); 238 + ret = sprintf(buf, "%12phN\n", &id_buf[SM_CHIP_ID_OFFSET]); 268 239 269 240 kfree(id_buf); 270 241 ··· 281 268 282 269 static int __init meson_sm_probe(struct platform_device *pdev) 283 270 { 271 + struct device *dev = &pdev->dev; 284 272 const struct meson_sm_chip *chip; 273 + struct meson_sm_firmware *fw; 285 274 286 - chip = of_match_device(meson_sm_ids, &pdev->dev)->data; 275 + fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL); 276 + if (!fw) 277 + return -ENOMEM; 278 + 279 + chip = of_match_device(meson_sm_ids, dev)->data; 287 280 288 281 if (chip->cmd_shmem_in_base) { 289 - fw.sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base, 290 - chip->shmem_size); 291 - if (WARN_ON(!fw.sm_shmem_in_base)) 282 + fw->sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base, 283 + chip->shmem_size); 284 + if (WARN_ON(!fw->sm_shmem_in_base)) 292 285 goto out; 293 286 } 294 287 295 288 if (chip->cmd_shmem_out_base) { 296 - fw.sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base, 297 - chip->shmem_size); 298 - if (WARN_ON(!fw.sm_shmem_out_base)) 289 + fw->sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base, 290 + chip->shmem_size); 291 + if (WARN_ON(!fw->sm_shmem_out_base)) 299 292 goto out_in_base; 300 293 } 301 294 302 - fw.chip = chip; 295 + fw->chip = chip; 296 + 297 + platform_set_drvdata(pdev, fw); 298 + 303 299 pr_info("secure-monitor enabled\n"); 304 300 305 301 if (sysfs_create_group(&pdev->dev.kobj, &meson_sm_sysfs_attr_group)) ··· 317 295 return 0; 318 296 319 297 out_in_base: 320 - iounmap(fw.sm_shmem_in_base); 298 + iounmap(fw->sm_shmem_in_base); 321 299 out: 322 300 return -EINVAL; 323 301 }
+21 -3
drivers/nvmem/meson-efuse.c
··· 17 17 static int meson_efuse_read(void *context, unsigned int offset, 18 18 void *val, size_t bytes) 19 19 { 20 - return meson_sm_call_read((u8 *)val, bytes, SM_EFUSE_READ, offset, 20 + struct meson_sm_firmware *fw = context; 21 + 22 + return meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset, 21 23 bytes, 0, 0, 0); 22 24 } 23 25 24 26 static int meson_efuse_write(void *context, unsigned int offset, 25 27 void *val, size_t bytes) 26 28 { 27 - return meson_sm_call_write((u8 *)val, bytes, SM_EFUSE_WRITE, offset, 29 + struct meson_sm_firmware *fw = context; 30 + 31 + return meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset, 28 32 bytes, 0, 0, 0); 29 33 } 30 34 ··· 41 37 static int meson_efuse_probe(struct platform_device *pdev) 42 38 { 43 39 struct device *dev = &pdev->dev; 40 + struct meson_sm_firmware *fw; 41 + struct device_node *sm_np; 44 42 struct nvmem_device *nvmem; 45 43 struct nvmem_config *econfig; 46 44 struct clk *clk; 47 45 unsigned int size; 48 46 int ret; 47 + 48 + sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0); 49 + if (!sm_np) { 50 + dev_err(&pdev->dev, "no secure-monitor node\n"); 51 + return -ENODEV; 52 + } 53 + 54 + fw = meson_sm_get(sm_np); 55 + of_node_put(sm_np); 56 + if (!fw) 57 + return -EPROBE_DEFER; 49 58 50 59 clk = devm_clk_get(dev, NULL); 51 60 if (IS_ERR(clk)) { ··· 82 65 return ret; 83 66 } 84 67 85 - if (meson_sm_call(SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) { 68 + if (meson_sm_call(fw, SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) { 86 69 dev_err(dev, "failed to get max user"); 87 70 return -EINVAL; 88 71 } ··· 98 81 econfig->reg_read = meson_efuse_read; 99 82 econfig->reg_write = meson_efuse_write; 100 83 econfig->size = size; 84 + econfig->priv = fw; 101 85 102 86 nvmem = devm_nvmem_register(&pdev->dev, econfig); 103 87
+3
drivers/soc/amlogic/meson-gx-socinfo.c
··· 40 40 { "G12A", 0x28 }, 41 41 { "G12B", 0x29 }, 42 42 { "SM1", 0x2b }, 43 + { "A1", 0x2c }, 43 44 }; 44 45 45 46 static const struct meson_gx_package_id { ··· 69 68 { "S922X", 0x29, 0x40, 0xf0 }, 70 69 { "A311D", 0x29, 0x10, 0xf0 }, 71 70 { "S905X3", 0x2b, 0x5, 0xf }, 71 + { "S905D3", 0x2b, 0xb0, 0xf0 }, 72 + { "A113L", 0x2c, 0x0, 0xf8 }, 72 73 }; 73 74 74 75 static inline unsigned int socinfo_to_major(u32 socinfo)
+9 -6
include/linux/firmware/meson/meson_sm.h
··· 16 16 17 17 struct meson_sm_firmware; 18 18 19 - int meson_sm_call(unsigned int cmd_index, u32 *ret, u32 arg0, u32 arg1, 20 - u32 arg2, u32 arg3, u32 arg4); 21 - int meson_sm_call_write(void *buffer, unsigned int b_size, unsigned int cmd_index, 22 - u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4); 23 - int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index, 24 - u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4); 19 + int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index, 20 + u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4); 21 + int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer, 22 + unsigned int b_size, unsigned int cmd_index, u32 arg0, 23 + u32 arg1, u32 arg2, u32 arg3, u32 arg4); 24 + int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer, 25 + unsigned int bsize, unsigned int cmd_index, u32 arg0, 26 + u32 arg1, u32 arg2, u32 arg3, u32 arg4); 27 + struct meson_sm_firmware *meson_sm_get(struct device_node *firmware_node); 25 28 26 29 #endif /* _MESON_SM_FW_H_ */