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

x86/platform/mellanox: Introduce support for Mellanox systems platform

Enable system support for the Mellanox Technologies platform, which
provides support for the next Mellanox basic systems: "msx6710",
"msx6720", "msb7700", "msn2700", "msx1410", "msn2410", "msb7800",
"msn2740", "msn2100" and also various number of derivative systems from
the above basic types.

The Kconfig controlling compilation of this code is: MLX_PLATFORM

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Cc: jiri@resnulli.us
Cc: gregkh@linuxfoundation.org
Cc: platform-driver-x86@vger.kernel.org
Cc: geert@linux-m68k.org
Cc: linux@roeck-us.net
Cc: akpm@linux-foundation.org
Cc: mchehab@kernel.org
Cc: davem@davemloft.net
Cc: kvalo@codeaurora.org
Link: http://lkml.kernel.org/r/1474578822-33805-1-git-send-email-vadimp@mellanox.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

authored by

Vadim Pasternak and committed by
Thomas Gleixner
58cbbee2 4f059d51

+286
+6
MAINTAINERS
··· 7668 7668 Q: http://patchwork.ozlabs.org/project/netdev/list/ 7669 7669 F: drivers/net/ethernet/mellanox/mlxsw/ 7670 7670 7671 + MELLANOX PLATFORM DRIVER 7672 + M: Vadim Pasternak <vadimp@mellanox.com> 7673 + L: platform-driver-x86@vger.kernel.org 7674 + S: Supported 7675 + F: arch/x86/platform/mellanox/mlx-platform.c 7676 + 7671 7677 SOFT-ROCE DRIVER (rxe) 7672 7678 M: Moni Shoua <monis@mellanox.com> 7673 7679 L: linux-rdma@vger.kernel.org
+12
arch/x86/Kconfig
··· 549 549 Say Y here if you have a Quark based system such as the Arduino 550 550 compatible Intel Galileo. 551 551 552 + config MLX_PLATFORM 553 + tristate "Mellanox Technologies platform support" 554 + depends on X86_64 555 + depends on X86_EXTENDED_PLATFORM 556 + ---help--- 557 + This option enables system support for the Mellanox Technologies 558 + platform. 559 + 560 + Say Y here if you are building a kernel for Mellanox system. 561 + 562 + Otherwise, say N. 563 + 552 564 config X86_INTEL_LPSS 553 565 bool "Intel Low Power Subsystem Support" 554 566 depends on X86 && ACPI
+1
arch/x86/platform/Makefile
··· 8 8 obj-y += intel/ 9 9 obj-y += intel-mid/ 10 10 obj-y += intel-quark/ 11 + obj-y += mellanox/ 11 12 obj-y += olpc/ 12 13 obj-y += scx200/ 13 14 obj-y += sfi/
+1
arch/x86/platform/mellanox/Makefile
··· 1 + obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o
+266
arch/x86/platform/mellanox/mlx-platform.c
··· 1 + /* 2 + * arch/x86/platform/mellanox/mlx-platform.c 3 + * Copyright (c) 2016 Mellanox Technologies. All rights reserved. 4 + * Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com> 5 + * 6 + * Redistribution and use in source and binary forms, with or without 7 + * modification, are permitted provided that the following conditions are met: 8 + * 9 + * 1. Redistributions of source code must retain the above copyright 10 + * notice, this list of conditions and the following disclaimer. 11 + * 2. Redistributions in binary form must reproduce the above copyright 12 + * notice, this list of conditions and the following disclaimer in the 13 + * documentation and/or other materials provided with the distribution. 14 + * 3. Neither the names of the copyright holders nor the names of its 15 + * contributors may be used to endorse or promote products derived from 16 + * this software without specific prior written permission. 17 + * 18 + * Alternatively, this software may be distributed under the terms of the 19 + * GNU General Public License ("GPL") version 2 as published by the Free 20 + * Software Foundation. 21 + * 22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 26 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 + * POSSIBILITY OF SUCH DAMAGE. 33 + */ 34 + 35 + #include <linux/device.h> 36 + #include <linux/dmi.h> 37 + #include <linux/i2c.h> 38 + #include <linux/i2c-mux.h> 39 + #include <linux/module.h> 40 + #include <linux/platform_device.h> 41 + #include <linux/platform_data/i2c-mux-reg.h> 42 + 43 + #define MLX_PLAT_DEVICE_NAME "mlxplat" 44 + 45 + /* LPC bus IO offsets */ 46 + #define MLXPLAT_CPLD_LPC_I2C_BASE_ADRR 0x2000 47 + #define MLXPLAT_CPLD_LPC_REG_BASE_ADRR 0x2500 48 + #define MLXPLAT_CPLD_LPC_IO_RANGE 0x100 49 + #define MLXPLAT_CPLD_LPC_I2C_CH1_OFF 0xdb 50 + #define MLXPLAT_CPLD_LPC_I2C_CH2_OFF 0xda 51 + #define MLXPLAT_CPLD_LPC_PIO_OFFSET 0x10000UL 52 + #define MLXPLAT_CPLD_LPC_REG1 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \ 53 + MLXPLAT_CPLD_LPC_I2C_CH1_OFF) | \ 54 + MLXPLAT_CPLD_LPC_PIO_OFFSET) 55 + #define MLXPLAT_CPLD_LPC_REG2 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \ 56 + MLXPLAT_CPLD_LPC_I2C_CH2_OFF) | \ 57 + MLXPLAT_CPLD_LPC_PIO_OFFSET) 58 + 59 + /* Start channel numbers */ 60 + #define MLXPLAT_CPLD_CH1 2 61 + #define MLXPLAT_CPLD_CH2 10 62 + 63 + /* Number of LPC attached MUX platform devices */ 64 + #define MLXPLAT_CPLD_LPC_MUX_DEVS 2 65 + 66 + /* mlxplat_priv - platform private data 67 + * @pdev_i2c - i2c controller platform device 68 + * @pdev_mux - array of mux platform devices 69 + */ 70 + struct mlxplat_priv { 71 + struct platform_device *pdev_i2c; 72 + struct platform_device *pdev_mux[MLXPLAT_CPLD_LPC_MUX_DEVS]; 73 + }; 74 + 75 + /* Regions for LPC I2C controller and LPC base register space */ 76 + static const struct resource mlxplat_lpc_resources[] = { 77 + [0] = DEFINE_RES_NAMED(MLXPLAT_CPLD_LPC_I2C_BASE_ADRR, 78 + MLXPLAT_CPLD_LPC_IO_RANGE, 79 + "mlxplat_cpld_lpc_i2c_ctrl", IORESOURCE_IO), 80 + [1] = DEFINE_RES_NAMED(MLXPLAT_CPLD_LPC_REG_BASE_ADRR, 81 + MLXPLAT_CPLD_LPC_IO_RANGE, 82 + "mlxplat_cpld_lpc_regs", 83 + IORESOURCE_IO), 84 + }; 85 + 86 + /* Platform default channels */ 87 + static const int mlxplat_default_channels[][8] = { 88 + { 89 + MLXPLAT_CPLD_CH1, MLXPLAT_CPLD_CH1 + 1, MLXPLAT_CPLD_CH1 + 2, 90 + MLXPLAT_CPLD_CH1 + 3, MLXPLAT_CPLD_CH1 + 4, MLXPLAT_CPLD_CH1 + 91 + 5, MLXPLAT_CPLD_CH1 + 6, MLXPLAT_CPLD_CH1 + 7 92 + }, 93 + { 94 + MLXPLAT_CPLD_CH2, MLXPLAT_CPLD_CH2 + 1, MLXPLAT_CPLD_CH2 + 2, 95 + MLXPLAT_CPLD_CH2 + 3, MLXPLAT_CPLD_CH2 + 4, MLXPLAT_CPLD_CH2 + 96 + 5, MLXPLAT_CPLD_CH2 + 6, MLXPLAT_CPLD_CH2 + 7 97 + }, 98 + }; 99 + 100 + /* Platform channels for MSN21xx system family */ 101 + static const int mlxplat_msn21xx_channels[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; 102 + 103 + /* Platform mux data */ 104 + static struct i2c_mux_reg_platform_data mlxplat_mux_data[] = { 105 + { 106 + .parent = 1, 107 + .base_nr = MLXPLAT_CPLD_CH1, 108 + .write_only = 1, 109 + .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1, 110 + .reg_size = 1, 111 + .idle_in_use = 1, 112 + }, 113 + { 114 + .parent = 1, 115 + .base_nr = MLXPLAT_CPLD_CH2, 116 + .write_only = 1, 117 + .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2, 118 + .reg_size = 1, 119 + .idle_in_use = 1, 120 + }, 121 + 122 + }; 123 + 124 + static struct platform_device *mlxplat_dev; 125 + 126 + static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi) 127 + { 128 + int i; 129 + 130 + for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) { 131 + mlxplat_mux_data[i].values = mlxplat_default_channels[i]; 132 + mlxplat_mux_data[i].n_values = 133 + ARRAY_SIZE(mlxplat_default_channels[i]); 134 + } 135 + 136 + return 1; 137 + }; 138 + 139 + static int __init mlxplat_dmi_msn21xx_matched(const struct dmi_system_id *dmi) 140 + { 141 + int i; 142 + 143 + for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) { 144 + mlxplat_mux_data[i].values = mlxplat_msn21xx_channels; 145 + mlxplat_mux_data[i].n_values = 146 + ARRAY_SIZE(mlxplat_msn21xx_channels); 147 + } 148 + 149 + return 1; 150 + }; 151 + 152 + static struct dmi_system_id mlxplat_dmi_table[] __initdata = { 153 + { 154 + .callback = mlxplat_dmi_default_matched, 155 + .matches = { 156 + DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 157 + DMI_MATCH(DMI_PRODUCT_NAME, "MSN24"), 158 + }, 159 + }, 160 + { 161 + .callback = mlxplat_dmi_default_matched, 162 + .matches = { 163 + DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 164 + DMI_MATCH(DMI_PRODUCT_NAME, "MSN27"), 165 + }, 166 + }, 167 + { 168 + .callback = mlxplat_dmi_default_matched, 169 + .matches = { 170 + DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 171 + DMI_MATCH(DMI_PRODUCT_NAME, "MSB"), 172 + }, 173 + }, 174 + { 175 + .callback = mlxplat_dmi_default_matched, 176 + .matches = { 177 + DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 178 + DMI_MATCH(DMI_PRODUCT_NAME, "MSX"), 179 + }, 180 + }, 181 + { 182 + .callback = mlxplat_dmi_msn21xx_matched, 183 + .matches = { 184 + DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 185 + DMI_MATCH(DMI_PRODUCT_NAME, "MSN21"), 186 + }, 187 + }, 188 + { } 189 + }; 190 + 191 + static int __init mlxplat_init(void) 192 + { 193 + struct mlxplat_priv *priv; 194 + int i, err; 195 + 196 + if (!dmi_check_system(mlxplat_dmi_table)) 197 + return -ENODEV; 198 + 199 + mlxplat_dev = platform_device_register_simple(MLX_PLAT_DEVICE_NAME, -1, 200 + mlxplat_lpc_resources, 201 + ARRAY_SIZE(mlxplat_lpc_resources)); 202 + 203 + if (!mlxplat_dev) 204 + return -ENOMEM; 205 + 206 + priv = devm_kzalloc(&mlxplat_dev->dev, sizeof(struct mlxplat_priv), 207 + GFP_KERNEL); 208 + if (!priv) { 209 + err = -ENOMEM; 210 + goto fail_alloc; 211 + } 212 + platform_set_drvdata(mlxplat_dev, priv); 213 + 214 + priv->pdev_i2c = platform_device_register_simple("i2c_mlxcpld", -1, 215 + NULL, 0); 216 + if (IS_ERR(priv->pdev_i2c)) { 217 + err = PTR_ERR(priv->pdev_i2c); 218 + goto fail_alloc; 219 + }; 220 + 221 + for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) { 222 + priv->pdev_mux[i] = platform_device_register_resndata( 223 + &mlxplat_dev->dev, 224 + "i2c-mux-reg", i, NULL, 225 + 0, &mlxplat_mux_data[i], 226 + sizeof(mlxplat_mux_data[i])); 227 + if (IS_ERR(priv->pdev_mux[i])) { 228 + err = PTR_ERR(priv->pdev_mux[i]); 229 + goto fail_platform_mux_register; 230 + } 231 + } 232 + 233 + return 0; 234 + 235 + fail_platform_mux_register: 236 + for (i--; i > 0 ; i--) 237 + platform_device_unregister(priv->pdev_mux[i]); 238 + platform_device_unregister(priv->pdev_i2c); 239 + fail_alloc: 240 + platform_device_unregister(mlxplat_dev); 241 + 242 + return err; 243 + } 244 + module_init(mlxplat_init); 245 + 246 + static void __exit mlxplat_exit(void) 247 + { 248 + struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev); 249 + int i; 250 + 251 + for (i = ARRAY_SIZE(mlxplat_mux_data) - 1; i >= 0 ; i--) 252 + platform_device_unregister(priv->pdev_mux[i]); 253 + 254 + platform_device_unregister(priv->pdev_i2c); 255 + platform_device_unregister(mlxplat_dev); 256 + } 257 + module_exit(mlxplat_exit); 258 + 259 + MODULE_AUTHOR("Vadim Pasternak (vadimp@mellanox.com)"); 260 + MODULE_DESCRIPTION("Mellanox platform driver"); 261 + MODULE_LICENSE("Dual BSD/GPL"); 262 + MODULE_ALIAS("dmi:*:*Mellanox*:MSN24*:"); 263 + MODULE_ALIAS("dmi:*:*Mellanox*:MSN27*:"); 264 + MODULE_ALIAS("dmi:*:*Mellanox*:MSB*:"); 265 + MODULE_ALIAS("dmi:*:*Mellanox*:MSX*:"); 266 + MODULE_ALIAS("dmi:*:*Mellanox*:MSN21*:");