aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/mlx-platform.c
diff options
context:
space:
mode:
authorVadim Pasternak <vadimp@mellanox.com>2018-01-22 22:55:11 -0500
committerDarren Hart (VMware) <dvhart@infradead.org>2018-01-31 13:36:49 -0500
commitc6acad68eb2dbffd0497f91b206de5c362f59ee4 (patch)
tree2115350d7eb993b12a15d4f18352d29681ab1278 /drivers/platform/x86/mlx-platform.c
parent752849e69715fdc2190945f5532d70e8c80bf384 (diff)
platform/mellanox: mlxreg-hotplug: Modify to use a regmap interface
Restructure mlxreg header for unification of hotplug item definitions. Unify hotplug items to allow any kind of item (power controller, fan eeprom, psu eeprom, asic health) in common way. Use a hardware independent regmap interface, enabling the support of hotplug events over programmable devices attached to different bus types, such as I2C, LPC, or SPI. Add a device node to the mlxreg_core_data structure. Signed-off-by: Vadim Pasternak <vadimp@mellanox.com> Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com> [dvhart: spelling corrections, refactor device node introduction] Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
Diffstat (limited to 'drivers/platform/x86/mlx-platform.c')
-rw-r--r--drivers/platform/x86/mlx-platform.c231
1 files changed, 182 insertions, 49 deletions
diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
index 56017143d6a9..03c9e7a76d89 100644
--- a/drivers/platform/x86/mlx-platform.c
+++ b/drivers/platform/x86/mlx-platform.c
@@ -35,20 +35,22 @@
35#include <linux/dmi.h> 35#include <linux/dmi.h>
36#include <linux/i2c.h> 36#include <linux/i2c.h>
37#include <linux/i2c-mux.h> 37#include <linux/i2c-mux.h>
38#include <linux/io.h>
38#include <linux/module.h> 39#include <linux/module.h>
39#include <linux/platform_device.h> 40#include <linux/platform_device.h>
40#include <linux/platform_data/i2c-mux-reg.h> 41#include <linux/platform_data/i2c-mux-reg.h>
41#include <linux/platform_data/mlxreg.h> 42#include <linux/platform_data/mlxreg.h>
43#include <linux/regmap.h>
42 44
43#define MLX_PLAT_DEVICE_NAME "mlxplat" 45#define MLX_PLAT_DEVICE_NAME "mlxplat"
44 46
45/* LPC bus IO offsets */ 47/* LPC bus IO offsets */
46#define MLXPLAT_CPLD_LPC_I2C_BASE_ADRR 0x2000 48#define MLXPLAT_CPLD_LPC_I2C_BASE_ADRR 0x2000
47#define MLXPLAT_CPLD_LPC_REG_BASE_ADRR 0x2500 49#define MLXPLAT_CPLD_LPC_REG_BASE_ADRR 0x2500
48#define MLXPLAT_CPLD_LPC_REG_AGGR_ADRR 0x253a 50#define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET 0x3a
49#define MLXPLAT_CPLD_LPC_REG_PSU_ADRR 0x2558 51#define MLXPLAT_CPLD_LPC_REG_PSU_OFFSET 0x58
50#define MLXPLAT_CPLD_LPC_REG_PWR_ADRR 0x2564 52#define MLXPLAT_CPLD_LPC_REG_PWR_OFFSET 0x64
51#define MLXPLAT_CPLD_LPC_REG_FAN_ADRR 0x2588 53#define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET 0x88
52#define MLXPLAT_CPLD_LPC_IO_RANGE 0x100 54#define MLXPLAT_CPLD_LPC_IO_RANGE 0x100
53#define MLXPLAT_CPLD_LPC_I2C_CH1_OFF 0xdb 55#define MLXPLAT_CPLD_LPC_I2C_CH1_OFF 0xdb
54#define MLXPLAT_CPLD_LPC_I2C_CH2_OFF 0xda 56#define MLXPLAT_CPLD_LPC_I2C_CH2_OFF 0xda
@@ -138,78 +140,194 @@ static struct i2c_mux_reg_platform_data mlxplat_mux_data[] = {
138}; 140};
139 141
140/* Platform hotplug devices */ 142/* Platform hotplug devices */
141static struct mlxreg_hotplug_device mlxplat_mlxcpld_psu[] = { 143static struct i2c_board_info mlxplat_mlxcpld_psu[] = {
142 { 144 {
143 .brdinfo = { I2C_BOARD_INFO("24c02", 0x51) }, 145 I2C_BOARD_INFO("24c02", 0x51),
144 .nr = 10,
145 }, 146 },
146 { 147 {
147 .brdinfo = { I2C_BOARD_INFO("24c02", 0x50) }, 148 I2C_BOARD_INFO("24c02", 0x50),
148 .nr = 10,
149 }, 149 },
150}; 150};
151 151
152static struct mlxreg_hotplug_device mlxplat_mlxcpld_pwr[] = { 152static struct i2c_board_info mlxplat_mlxcpld_pwr[] = {
153 { 153 {
154 .brdinfo = { I2C_BOARD_INFO("dps460", 0x59) }, 154 I2C_BOARD_INFO("dps460", 0x59),
155 .nr = 10,
156 }, 155 },
157 { 156 {
158 .brdinfo = { I2C_BOARD_INFO("dps460", 0x58) }, 157 I2C_BOARD_INFO("dps460", 0x58),
159 .nr = 10,
160 }, 158 },
161}; 159};
162 160
163static struct mlxreg_hotplug_device mlxplat_mlxcpld_fan[] = { 161static struct i2c_board_info mlxplat_mlxcpld_fan[] = {
164 { 162 {
165 .brdinfo = { I2C_BOARD_INFO("24c32", 0x50) }, 163 I2C_BOARD_INFO("24c32", 0x50),
166 .nr = 11,
167 }, 164 },
168 { 165 {
169 .brdinfo = { I2C_BOARD_INFO("24c32", 0x50) }, 166 I2C_BOARD_INFO("24c32", 0x50),
170 .nr = 12,
171 }, 167 },
172 { 168 {
173 .brdinfo = { I2C_BOARD_INFO("24c32", 0x50) }, 169 I2C_BOARD_INFO("24c32", 0x50),
174 .nr = 13,
175 }, 170 },
176 { 171 {
177 .brdinfo = { I2C_BOARD_INFO("24c32", 0x50) }, 172 I2C_BOARD_INFO("24c32", 0x50),
178 .nr = 14,
179 }, 173 },
180}; 174};
181 175
182/* Platform hotplug default data */ 176/* Platform hotplug default data */
177static struct mlxreg_core_data mlxplat_mlxcpld_default_psu_items_data[] = {
178 {
179 .label = "psu1",
180 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
181 .mask = BIT(0),
182 .hpdev.brdinfo = &mlxplat_mlxcpld_psu[0],
183 .hpdev.nr = 10,
184 },
185 {
186 .label = "psu2",
187 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
188 .mask = BIT(1),
189 .hpdev.brdinfo = &mlxplat_mlxcpld_psu[1],
190 .hpdev.nr = 10,
191 },
192};
193
194static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_items_data[] = {
195 {
196 .label = "pwr1",
197 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
198 .mask = BIT(0),
199 .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
200 .hpdev.nr = 10,
201 },
202 {
203 .label = "pwr2",
204 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
205 .mask = BIT(1),
206 .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
207 .hpdev.nr = 10,
208 },
209};
210
211static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_items_data[] = {
212 {
213 .label = "fan1",
214 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
215 .mask = BIT(0),
216 .hpdev.brdinfo = &mlxplat_mlxcpld_fan[0],
217 .hpdev.nr = 11,
218 },
219 {
220 .label = "fan2",
221 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
222 .mask = BIT(1),
223 .hpdev.brdinfo = &mlxplat_mlxcpld_fan[1],
224 .hpdev.nr = 12,
225 },
226 {
227 .label = "fan3",
228 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
229 .mask = BIT(2),
230 .hpdev.brdinfo = &mlxplat_mlxcpld_fan[2],
231 .hpdev.nr = 13,
232 },
233 {
234 .label = "fan4",
235 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
236 .mask = BIT(3),
237 .hpdev.brdinfo = &mlxplat_mlxcpld_fan[3],
238 .hpdev.nr = 14,
239 },
240};
241
242static struct mlxreg_core_item mlxplat_mlxcpld_default_items[] = {
243 {
244 .data = mlxplat_mlxcpld_default_psu_items_data,
245 .aggr_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF,
246 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
247 .mask = MLXPLAT_CPLD_PSU_MASK,
248 .count = ARRAY_SIZE(mlxplat_mlxcpld_psu),
249 .inversed = 1,
250 .health = false,
251 },
252 {
253 .data = mlxplat_mlxcpld_default_pwr_items_data,
254 .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
255 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
256 .mask = MLXPLAT_CPLD_PWR_MASK,
257 .count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
258 .inversed = 0,
259 .health = false,
260 },
261 {
262 .data = mlxplat_mlxcpld_default_fan_items_data,
263 .aggr_mask = MLXPLAT_CPLD_AGGR_FAN_MASK_DEF,
264 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
265 .mask = MLXPLAT_CPLD_FAN_MASK,
266 .count = ARRAY_SIZE(mlxplat_mlxcpld_fan),
267 .inversed = 1,
268 .health = false,
269 },
270};
271
183static 272static
184struct mlxreg_hotplug_platform_data mlxplat_mlxcpld_default_data = { 273struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_data = {
185 .top_aggr_offset = MLXPLAT_CPLD_LPC_REG_AGGR_ADRR, 274 .items = mlxplat_mlxcpld_default_items,
186 .top_aggr_mask = MLXPLAT_CPLD_AGGR_MASK_DEF, 275 .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_items),
187 .top_aggr_psu_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF, 276 .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
188 .psu_reg_offset = MLXPLAT_CPLD_LPC_REG_PSU_ADRR, 277 .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
189 .psu_mask = MLXPLAT_CPLD_PSU_MASK,
190 .psu_count = ARRAY_SIZE(mlxplat_mlxcpld_psu),
191 .psu = mlxplat_mlxcpld_psu,
192 .top_aggr_pwr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
193 .pwr_reg_offset = MLXPLAT_CPLD_LPC_REG_PWR_ADRR,
194 .pwr_mask = MLXPLAT_CPLD_PWR_MASK,
195 .pwr_count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
196 .pwr = mlxplat_mlxcpld_pwr,
197 .top_aggr_fan_mask = MLXPLAT_CPLD_AGGR_FAN_MASK_DEF,
198 .fan_reg_offset = MLXPLAT_CPLD_LPC_REG_FAN_ADRR,
199 .fan_mask = MLXPLAT_CPLD_FAN_MASK,
200 .fan_count = ARRAY_SIZE(mlxplat_mlxcpld_fan),
201 .fan = mlxplat_mlxcpld_fan,
202}; 278};
203 279
204/* Platform hotplug MSN21xx system family data */ 280/* Platform hotplug MSN21xx system family data */
281static struct mlxreg_core_item mlxplat_mlxcpld_msn21xx_items[] = {
282 {
283 .data = mlxplat_mlxcpld_default_pwr_items_data,
284 .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
285 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
286 .mask = MLXPLAT_CPLD_PWR_MASK,
287 .count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
288 .inversed = 0,
289 .health = false,
290 },
291};
292
205static 293static
206struct mlxreg_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = { 294struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = {
207 .top_aggr_offset = MLXPLAT_CPLD_LPC_REG_AGGR_ADRR, 295 .items = mlxplat_mlxcpld_msn21xx_items,
208 .top_aggr_mask = MLXPLAT_CPLD_AGGR_MASK_MSN21XX, 296 .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_items),
209 .top_aggr_pwr_mask = MLXPLAT_CPLD_AGGR_MASK_MSN21XX, 297 .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
210 .pwr_reg_offset = MLXPLAT_CPLD_LPC_REG_PWR_ADRR, 298 .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
211 .pwr_mask = MLXPLAT_CPLD_PWR_MASK, 299};
212 .pwr_count = ARRAY_SIZE(mlxplat_mlxcpld_pwr), 300
301struct mlxplat_mlxcpld_regmap_context {
302 void __iomem *base;
303};
304
305static struct mlxplat_mlxcpld_regmap_context mlxplat_mlxcpld_regmap_ctx;
306
307static int
308mlxplat_mlxcpld_reg_read(void *context, unsigned int reg, unsigned int *val)
309{
310 struct mlxplat_mlxcpld_regmap_context *ctx = context;
311
312 *val = ioread8(ctx->base + reg);
313 return 0;
314}
315
316static int
317mlxplat_mlxcpld_reg_write(void *context, unsigned int reg, unsigned int val)
318{
319 struct mlxplat_mlxcpld_regmap_context *ctx = context;
320
321 iowrite8(val, ctx->base + reg);
322 return 0;
323}
324
325static const struct regmap_config mlxplat_mlxcpld_regmap_config = {
326 .reg_bits = 8,
327 .val_bits = 8,
328 .max_register = 255,
329 .reg_read = mlxplat_mlxcpld_reg_read,
330 .reg_write = mlxplat_mlxcpld_reg_write,
213}; 331};
214 332
215static struct resource mlxplat_mlxcpld_resources[] = { 333static struct resource mlxplat_mlxcpld_resources[] = {
@@ -217,7 +335,7 @@ static struct resource mlxplat_mlxcpld_resources[] = {
217}; 335};
218 336
219static struct platform_device *mlxplat_dev; 337static struct platform_device *mlxplat_dev;
220static struct mlxreg_hotplug_platform_data *mlxplat_hotplug; 338static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug;
221 339
222static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi) 340static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
223{ 341{
@@ -328,6 +446,21 @@ static int __init mlxplat_init(void)
328 } 446 }
329 } 447 }
330 448
449 mlxplat_mlxcpld_regmap_ctx.base = devm_ioport_map(&mlxplat_dev->dev,
450 mlxplat_lpc_resources[1].start, 1);
451 if (IS_ERR(mlxplat_mlxcpld_regmap_ctx.base)) {
452 err = PTR_ERR(mlxplat_mlxcpld_regmap_ctx.base);
453 goto fail_platform_mux_register;
454 }
455
456 mlxplat_hotplug->regmap = devm_regmap_init(&mlxplat_dev->dev, NULL,
457 &mlxplat_mlxcpld_regmap_ctx,
458 &mlxplat_mlxcpld_regmap_config);
459 if (IS_ERR(mlxplat_hotplug->regmap)) {
460 err = PTR_ERR(mlxplat_hotplug->regmap);
461 goto fail_platform_mux_register;
462 }
463
331 priv->pdev_hotplug = platform_device_register_resndata( 464 priv->pdev_hotplug = platform_device_register_resndata(
332 &mlxplat_dev->dev, "mlxreg-hotplug", 465 &mlxplat_dev->dev, "mlxreg-hotplug",
333 PLATFORM_DEVID_NONE, 466 PLATFORM_DEVID_NONE,