diff options
Diffstat (limited to 'drivers/net/sfc/sfe4001.c')
| -rw-r--r-- | drivers/net/sfc/sfe4001.c | 126 |
1 files changed, 66 insertions, 60 deletions
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index 66a0d1442aba..b27849523990 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c | |||
| @@ -106,28 +106,27 @@ | |||
| 106 | 106 | ||
| 107 | static const u8 xgphy_max_temperature = 90; | 107 | static const u8 xgphy_max_temperature = 90; |
| 108 | 108 | ||
| 109 | void sfe4001_poweroff(struct efx_nic *efx) | 109 | static void sfe4001_poweroff(struct efx_nic *efx) |
| 110 | { | 110 | { |
| 111 | struct efx_i2c_interface *i2c = &efx->i2c; | 111 | struct i2c_client *ioexp_client = efx->board_info.ioexp_client; |
| 112 | struct i2c_client *hwmon_client = efx->board_info.hwmon_client; | ||
| 112 | 113 | ||
| 113 | u8 cfg, out, in; | 114 | /* Turn off all power rails and disable outputs */ |
| 115 | i2c_smbus_write_byte_data(ioexp_client, P0_OUT, 0xff); | ||
| 116 | i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG, 0xff); | ||
| 117 | i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0xff); | ||
| 114 | 118 | ||
| 115 | EFX_INFO(efx, "%s\n", __func__); | 119 | /* Clear any over-temperature alert */ |
| 116 | 120 | i2c_smbus_read_byte_data(hwmon_client, RSL); | |
| 117 | /* Turn off all power rails */ | 121 | } |
| 118 | out = 0xff; | ||
| 119 | efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | ||
| 120 | |||
| 121 | /* Disable port 1 outputs on IO expander */ | ||
| 122 | cfg = 0xff; | ||
| 123 | efx_i2c_write(i2c, PCA9539, P1_CONFIG, &cfg, 1); | ||
| 124 | 122 | ||
| 125 | /* Disable port 0 outputs on IO expander */ | 123 | static void sfe4001_fini(struct efx_nic *efx) |
| 126 | cfg = 0xff; | 124 | { |
| 127 | efx_i2c_write(i2c, PCA9539, P0_CONFIG, &cfg, 1); | 125 | EFX_INFO(efx, "%s\n", __func__); |
| 128 | 126 | ||
| 129 | /* Clear any over-temperature alert */ | 127 | sfe4001_poweroff(efx); |
| 130 | efx_i2c_read(i2c, MAX6647, RSL, &in, 1); | 128 | i2c_unregister_device(efx->board_info.ioexp_client); |
| 129 | i2c_unregister_device(efx->board_info.hwmon_client); | ||
| 131 | } | 130 | } |
| 132 | 131 | ||
| 133 | /* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected | 132 | /* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected |
| @@ -143,14 +142,26 @@ MODULE_PARM_DESC(phy_flash_cfg, | |||
| 143 | * be turned on before the PHY can be used. | 142 | * be turned on before the PHY can be used. |
| 144 | * Context: Process context, rtnl lock held | 143 | * Context: Process context, rtnl lock held |
| 145 | */ | 144 | */ |
| 146 | int sfe4001_poweron(struct efx_nic *efx) | 145 | int sfe4001_init(struct efx_nic *efx) |
| 147 | { | 146 | { |
| 148 | struct efx_i2c_interface *i2c = &efx->i2c; | 147 | struct i2c_client *hwmon_client, *ioexp_client; |
| 149 | unsigned int count; | 148 | unsigned int count; |
| 150 | int rc; | 149 | int rc; |
| 151 | u8 out, in, cfg; | 150 | u8 out; |
| 152 | efx_dword_t reg; | 151 | efx_dword_t reg; |
| 153 | 152 | ||
| 153 | hwmon_client = i2c_new_dummy(&efx->i2c_adap, MAX6647); | ||
| 154 | if (!hwmon_client) | ||
| 155 | return -EIO; | ||
| 156 | efx->board_info.hwmon_client = hwmon_client; | ||
| 157 | |||
| 158 | ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539); | ||
| 159 | if (!ioexp_client) { | ||
| 160 | rc = -EIO; | ||
| 161 | goto fail_hwmon; | ||
| 162 | } | ||
| 163 | efx->board_info.ioexp_client = ioexp_client; | ||
| 164 | |||
| 154 | /* 10Xpress has fixed-function LED pins, so there is no board-specific | 165 | /* 10Xpress has fixed-function LED pins, so there is no board-specific |
| 155 | * blink code. */ | 166 | * blink code. */ |
| 156 | efx->board_info.blink = tenxpress_phy_blink; | 167 | efx->board_info.blink = tenxpress_phy_blink; |
| @@ -166,44 +177,45 @@ int sfe4001_poweron(struct efx_nic *efx) | |||
| 166 | falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC); | 177 | falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC); |
| 167 | udelay(10); | 178 | udelay(10); |
| 168 | 179 | ||
| 180 | efx->board_info.fini = sfe4001_fini; | ||
| 181 | |||
| 169 | /* Set DSP over-temperature alert threshold */ | 182 | /* Set DSP over-temperature alert threshold */ |
| 170 | EFX_INFO(efx, "DSP cut-out at %dC\n", xgphy_max_temperature); | 183 | EFX_INFO(efx, "DSP cut-out at %dC\n", xgphy_max_temperature); |
| 171 | rc = efx_i2c_write(i2c, MAX6647, WLHO, | 184 | rc = i2c_smbus_write_byte_data(hwmon_client, WLHO, |
| 172 | &xgphy_max_temperature, 1); | 185 | xgphy_max_temperature); |
| 173 | if (rc) | 186 | if (rc) |
| 174 | goto fail1; | 187 | goto fail_ioexp; |
| 175 | 188 | ||
| 176 | /* Read it back and verify */ | 189 | /* Read it back and verify */ |
| 177 | rc = efx_i2c_read(i2c, MAX6647, RLHN, &in, 1); | 190 | rc = i2c_smbus_read_byte_data(hwmon_client, RLHN); |
| 178 | if (rc) | 191 | if (rc < 0) |
| 179 | goto fail1; | 192 | goto fail_ioexp; |
| 180 | if (in != xgphy_max_temperature) { | 193 | if (rc != xgphy_max_temperature) { |
| 181 | rc = -EFAULT; | 194 | rc = -EFAULT; |
| 182 | goto fail1; | 195 | goto fail_ioexp; |
| 183 | } | 196 | } |
| 184 | 197 | ||
| 185 | /* Clear any previous over-temperature alert */ | 198 | /* Clear any previous over-temperature alert */ |
| 186 | rc = efx_i2c_read(i2c, MAX6647, RSL, &in, 1); | 199 | rc = i2c_smbus_read_byte_data(hwmon_client, RSL); |
| 187 | if (rc) | 200 | if (rc < 0) |
| 188 | goto fail1; | 201 | goto fail_ioexp; |
| 189 | 202 | ||
| 190 | /* Enable port 0 and port 1 outputs on IO expander */ | 203 | /* Enable port 0 and port 1 outputs on IO expander */ |
| 191 | cfg = 0x00; | 204 | rc = i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0x00); |
| 192 | rc = efx_i2c_write(i2c, PCA9539, P0_CONFIG, &cfg, 1); | ||
| 193 | if (rc) | 205 | if (rc) |
| 194 | goto fail1; | 206 | goto fail_ioexp; |
| 195 | cfg = 0xff & ~(1 << P1_SPARE_LBN); | 207 | rc = i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG, |
| 196 | rc = efx_i2c_write(i2c, PCA9539, P1_CONFIG, &cfg, 1); | 208 | 0xff & ~(1 << P1_SPARE_LBN)); |
| 197 | if (rc) | 209 | if (rc) |
| 198 | goto fail2; | 210 | goto fail_on; |
| 199 | 211 | ||
| 200 | /* Turn all power off then wait 1 sec. This ensures PHY is reset */ | 212 | /* Turn all power off then wait 1 sec. This ensures PHY is reset */ |
| 201 | out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) | | 213 | out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) | |
| 202 | (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) | | 214 | (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) | |
| 203 | (0 << P0_EN_1V0X_LBN)); | 215 | (0 << P0_EN_1V0X_LBN)); |
| 204 | rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | 216 | rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out); |
| 205 | if (rc) | 217 | if (rc) |
| 206 | goto fail3; | 218 | goto fail_on; |
| 207 | 219 | ||
| 208 | schedule_timeout_uninterruptible(HZ); | 220 | schedule_timeout_uninterruptible(HZ); |
| 209 | count = 0; | 221 | count = 0; |
| @@ -215,26 +227,26 @@ int sfe4001_poweron(struct efx_nic *efx) | |||
| 215 | if (sfe4001_phy_flash_cfg) | 227 | if (sfe4001_phy_flash_cfg) |
| 216 | out |= 1 << P0_EN_3V3X_LBN; | 228 | out |= 1 << P0_EN_3V3X_LBN; |
| 217 | 229 | ||
| 218 | rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | 230 | rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out); |
| 219 | if (rc) | 231 | if (rc) |
| 220 | goto fail3; | 232 | goto fail_on; |
| 221 | msleep(10); | 233 | msleep(10); |
| 222 | 234 | ||
| 223 | /* Turn on 1V power rail */ | 235 | /* Turn on 1V power rail */ |
| 224 | out &= ~(1 << P0_EN_1V0X_LBN); | 236 | out &= ~(1 << P0_EN_1V0X_LBN); |
| 225 | rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | 237 | rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out); |
| 226 | if (rc) | 238 | if (rc) |
| 227 | goto fail3; | 239 | goto fail_on; |
| 228 | 240 | ||
| 229 | EFX_INFO(efx, "waiting for power (attempt %d)...\n", count); | 241 | EFX_INFO(efx, "waiting for power (attempt %d)...\n", count); |
| 230 | 242 | ||
| 231 | schedule_timeout_uninterruptible(HZ); | 243 | schedule_timeout_uninterruptible(HZ); |
| 232 | 244 | ||
| 233 | /* Check DSP is powered */ | 245 | /* Check DSP is powered */ |
| 234 | rc = efx_i2c_read(i2c, PCA9539, P1_IN, &in, 1); | 246 | rc = i2c_smbus_read_byte_data(ioexp_client, P1_IN); |
| 235 | if (rc) | 247 | if (rc < 0) |
| 236 | goto fail3; | 248 | goto fail_on; |
| 237 | if (in & (1 << P1_AFE_PWD_LBN)) | 249 | if (rc & (1 << P1_AFE_PWD_LBN)) |
| 238 | goto done; | 250 | goto done; |
| 239 | 251 | ||
| 240 | /* DSP doesn't look powered in flash config mode */ | 252 | /* DSP doesn't look powered in flash config mode */ |
| @@ -244,23 +256,17 @@ int sfe4001_poweron(struct efx_nic *efx) | |||
| 244 | 256 | ||
| 245 | EFX_INFO(efx, "timed out waiting for power\n"); | 257 | EFX_INFO(efx, "timed out waiting for power\n"); |
| 246 | rc = -ETIMEDOUT; | 258 | rc = -ETIMEDOUT; |
| 247 | goto fail3; | 259 | goto fail_on; |
| 248 | 260 | ||
| 249 | done: | 261 | done: |
| 250 | EFX_INFO(efx, "PHY is powered on\n"); | 262 | EFX_INFO(efx, "PHY is powered on\n"); |
| 251 | return 0; | 263 | return 0; |
| 252 | 264 | ||
| 253 | fail3: | 265 | fail_on: |
| 254 | /* Turn off all power rails */ | 266 | sfe4001_poweroff(efx); |
| 255 | out = 0xff; | 267 | fail_ioexp: |
| 256 | efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | 268 | i2c_unregister_device(ioexp_client); |
| 257 | /* Disable port 1 outputs on IO expander */ | 269 | fail_hwmon: |
| 258 | out = 0xff; | 270 | i2c_unregister_device(hwmon_client); |
| 259 | efx_i2c_write(i2c, PCA9539, P1_CONFIG, &out, 1); | ||
| 260 | fail2: | ||
| 261 | /* Disable port 0 outputs on IO expander */ | ||
| 262 | out = 0xff; | ||
| 263 | efx_i2c_write(i2c, PCA9539, P0_CONFIG, &out, 1); | ||
| 264 | fail1: | ||
| 265 | return rc; | 271 | return rc; |
| 266 | } | 272 | } |
