sunxi_sid.c (f26e8817b235d8764363bffcc9cbfc61867371f2) | sunxi_sid.c (4a72cda530f87ee0d96c4b79b9e1a865f7761659) |
---|---|
1/* 2 * Allwinner sunXi SoCs Security ID support. 3 * 4 * Copyright (c) 2013 Oliver Schinagl <oliver@schinagl.nl> 5 * Copyright (C) 2014 Maxime Ripard <maxime.ripard@free-electrons.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by --- 6 unchanged lines hidden (view full) --- 15 * GNU General Public License for more details. 16 */ 17 18#include <linux/device.h> 19#include <linux/io.h> 20#include <linux/module.h> 21#include <linux/nvmem-provider.h> 22#include <linux/of.h> | 1/* 2 * Allwinner sunXi SoCs Security ID support. 3 * 4 * Copyright (c) 2013 Oliver Schinagl <oliver@schinagl.nl> 5 * Copyright (C) 2014 Maxime Ripard <maxime.ripard@free-electrons.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by --- 6 unchanged lines hidden (view full) --- 15 * GNU General Public License for more details. 16 */ 17 18#include <linux/device.h> 19#include <linux/io.h> 20#include <linux/module.h> 21#include <linux/nvmem-provider.h> 22#include <linux/of.h> |
23#include <linux/of_device.h> |
|
23#include <linux/platform_device.h> 24#include <linux/slab.h> 25#include <linux/random.h> 26 27static struct nvmem_config econfig = { 28 .name = "sunxi-sid", 29 .read_only = true, 30 .stride = 4, 31 .word_size = 1, 32 .owner = THIS_MODULE, 33}; 34 | 24#include <linux/platform_device.h> 25#include <linux/slab.h> 26#include <linux/random.h> 27 28static struct nvmem_config econfig = { 29 .name = "sunxi-sid", 30 .read_only = true, 31 .stride = 4, 32 .word_size = 1, 33 .owner = THIS_MODULE, 34}; 35 |
36struct sunxi_sid_cfg { 37 u32 size; 38}; 39 |
|
35struct sunxi_sid { 36 void __iomem *base; 37}; 38 39/* We read the entire key, due to a 32 bit read alignment requirement. Since we 40 * want to return the requested byte, this results in somewhat slower code and 41 * uses 4 times more reads as needed but keeps code simpler. Since the SID is 42 * only very rarely probed, this is not really an issue. --- 24 unchanged lines hidden (view full) --- 67static int sunxi_sid_probe(struct platform_device *pdev) 68{ 69 struct device *dev = &pdev->dev; 70 struct resource *res; 71 struct nvmem_device *nvmem; 72 struct sunxi_sid *sid; 73 int ret, i, size; 74 char *randomness; | 40struct sunxi_sid { 41 void __iomem *base; 42}; 43 44/* We read the entire key, due to a 32 bit read alignment requirement. Since we 45 * want to return the requested byte, this results in somewhat slower code and 46 * uses 4 times more reads as needed but keeps code simpler. Since the SID is 47 * only very rarely probed, this is not really an issue. --- 24 unchanged lines hidden (view full) --- 72static int sunxi_sid_probe(struct platform_device *pdev) 73{ 74 struct device *dev = &pdev->dev; 75 struct resource *res; 76 struct nvmem_device *nvmem; 77 struct sunxi_sid *sid; 78 int ret, i, size; 79 char *randomness; |
80 const struct sunxi_sid_cfg *cfg; |
|
75 76 sid = devm_kzalloc(dev, sizeof(*sid), GFP_KERNEL); 77 if (!sid) 78 return -ENOMEM; 79 | 81 82 sid = devm_kzalloc(dev, sizeof(*sid), GFP_KERNEL); 83 if (!sid) 84 return -ENOMEM; 85 |
86 cfg = of_device_get_match_data(dev); 87 if (!cfg) 88 return -EINVAL; 89 |
|
80 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 81 sid->base = devm_ioremap_resource(dev, res); 82 if (IS_ERR(sid->base)) 83 return PTR_ERR(sid->base); 84 | 90 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 91 sid->base = devm_ioremap_resource(dev, res); 92 if (IS_ERR(sid->base)) 93 return PTR_ERR(sid->base); 94 |
85 size = resource_size(res) - 1; 86 econfig.size = resource_size(res); | 95 size = cfg->size; 96 97 econfig.size = size; |
87 econfig.dev = dev; 88 econfig.reg_read = sunxi_sid_read; 89 econfig.priv = sid; 90 nvmem = nvmem_register(&econfig); 91 if (IS_ERR(nvmem)) 92 return PTR_ERR(nvmem); 93 94 randomness = kzalloc(sizeof(u8) * (size), GFP_KERNEL); --- 19 unchanged lines hidden (view full) --- 114 115static int sunxi_sid_remove(struct platform_device *pdev) 116{ 117 struct nvmem_device *nvmem = platform_get_drvdata(pdev); 118 119 return nvmem_unregister(nvmem); 120} 121 | 98 econfig.dev = dev; 99 econfig.reg_read = sunxi_sid_read; 100 econfig.priv = sid; 101 nvmem = nvmem_register(&econfig); 102 if (IS_ERR(nvmem)) 103 return PTR_ERR(nvmem); 104 105 randomness = kzalloc(sizeof(u8) * (size), GFP_KERNEL); --- 19 unchanged lines hidden (view full) --- 125 126static int sunxi_sid_remove(struct platform_device *pdev) 127{ 128 struct nvmem_device *nvmem = platform_get_drvdata(pdev); 129 130 return nvmem_unregister(nvmem); 131} 132 |
133static const struct sunxi_sid_cfg sun4i_a10_cfg = { 134 .size = 0x10, 135}; 136 137static const struct sunxi_sid_cfg sun7i_a20_cfg = { 138 .size = 0x200, 139}; 140 |
|
122static const struct of_device_id sunxi_sid_of_match[] = { | 141static const struct of_device_id sunxi_sid_of_match[] = { |
123 { .compatible = "allwinner,sun4i-a10-sid" }, 124 { .compatible = "allwinner,sun7i-a20-sid" }, | 142 { .compatible = "allwinner,sun4i-a10-sid", .data = &sun4i_a10_cfg }, 143 { .compatible = "allwinner,sun7i-a20-sid", .data = &sun7i_a20_cfg }, |
125 {/* sentinel */}, 126}; 127MODULE_DEVICE_TABLE(of, sunxi_sid_of_match); 128 129static struct platform_driver sunxi_sid_driver = { 130 .probe = sunxi_sid_probe, 131 .remove = sunxi_sid_remove, 132 .driver = { 133 .name = "eeprom-sunxi-sid", 134 .of_match_table = sunxi_sid_of_match, 135 }, 136}; 137module_platform_driver(sunxi_sid_driver); 138 139MODULE_AUTHOR("Oliver Schinagl <oliver@schinagl.nl>"); 140MODULE_DESCRIPTION("Allwinner sunxi security id driver"); 141MODULE_LICENSE("GPL"); | 144 {/* sentinel */}, 145}; 146MODULE_DEVICE_TABLE(of, sunxi_sid_of_match); 147 148static struct platform_driver sunxi_sid_driver = { 149 .probe = sunxi_sid_probe, 150 .remove = sunxi_sid_remove, 151 .driver = { 152 .name = "eeprom-sunxi-sid", 153 .of_match_table = sunxi_sid_of_match, 154 }, 155}; 156module_platform_driver(sunxi_sid_driver); 157 158MODULE_AUTHOR("Oliver Schinagl <oliver@schinagl.nl>"); 159MODULE_DESCRIPTION("Allwinner sunxi security id driver"); 160MODULE_LICENSE("GPL"); |