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

phy: intel: Remove Thunder Bay eMMC PHY support

Remove Thunder Bay specific code as the product got cancelled
and there are no end customers or users.

Signed-off-by: A, Rashmi <rashmi.a@intel.com>
Reviewed-by: Hunter, Adrian <adrian.hunter@intel.com>
Link: https://lore.kernel.org/r/20230316120549.21486-4-rashmi.a@intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

A, Rashmi and committed by
Vinod Koul
69f27b45 fe15c26e

-520
-10
drivers/phy/intel/Kconfig
··· 46 46 select GENERIC_PHY 47 47 help 48 48 Enable this to support the Intel EMMC PHY 49 - 50 - config PHY_INTEL_THUNDERBAY_EMMC 51 - tristate "Intel Thunder Bay eMMC PHY driver" 52 - depends on OF && (ARCH_THUNDERBAY || COMPILE_TEST) 53 - select GENERIC_PHY 54 - help 55 - This option enables support for Intel Thunder Bay SoC eMMC PHY. 56 - 57 - To compile this driver as a module, choose M here: the module 58 - will be called phy-intel-thunderbay-emmc.ko.
-1
drivers/phy/intel/Makefile
··· 3 3 obj-$(CONFIG_PHY_INTEL_KEEMBAY_USB) += phy-intel-keembay-usb.o 4 4 obj-$(CONFIG_PHY_INTEL_LGM_COMBO) += phy-intel-lgm-combo.o 5 5 obj-$(CONFIG_PHY_INTEL_LGM_EMMC) += phy-intel-lgm-emmc.o 6 - obj-$(CONFIG_PHY_INTEL_THUNDERBAY_EMMC) += phy-intel-thunderbay-emmc.o
-509
drivers/phy/intel/phy-intel-thunderbay-emmc.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Intel ThunderBay eMMC PHY driver 4 - * 5 - * Copyright (C) 2021 Intel Corporation 6 - * 7 - */ 8 - 9 - #include <linux/clk.h> 10 - #include <linux/delay.h> 11 - #include <linux/io.h> 12 - #include <linux/iopoll.h> 13 - #include <linux/module.h> 14 - #include <linux/of.h> 15 - #include <linux/phy/phy.h> 16 - #include <linux/platform_device.h> 17 - 18 - /* eMMC/SD/SDIO core/phy configuration registers */ 19 - #define CTRL_CFG_0 0x00 20 - #define CTRL_CFG_1 0x04 21 - #define CTRL_PRESET_0 0x08 22 - #define CTRL_PRESET_1 0x0c 23 - #define CTRL_PRESET_2 0x10 24 - #define CTRL_PRESET_3 0x14 25 - #define CTRL_PRESET_4 0x18 26 - #define CTRL_CFG_2 0x1c 27 - #define CTRL_CFG_3 0x20 28 - #define PHY_CFG_0 0x24 29 - #define PHY_CFG_1 0x28 30 - #define PHY_CFG_2 0x2c 31 - #define PHYBIST_CTRL 0x30 32 - #define SDHC_STAT3 0x34 33 - #define PHY_STAT 0x38 34 - #define PHYBIST_STAT_0 0x3c 35 - #define PHYBIST_STAT_1 0x40 36 - #define EMMC_AXI 0x44 37 - 38 - /* CTRL_PRESET_3 */ 39 - #define CTRL_PRESET3_MASK GENMASK(31, 0) 40 - #define CTRL_PRESET3_SHIFT 0 41 - 42 - /* CTRL_CFG_0 bit fields */ 43 - #define SUPPORT_HS_MASK BIT(26) 44 - #define SUPPORT_HS_SHIFT 26 45 - 46 - #define SUPPORT_8B_MASK BIT(24) 47 - #define SUPPORT_8B_SHIFT 24 48 - 49 - /* CTRL_CFG_1 bit fields */ 50 - #define SUPPORT_SDR50_MASK BIT(28) 51 - #define SUPPORT_SDR50_SHIFT 28 52 - #define SLOT_TYPE_MASK GENMASK(27, 26) 53 - #define SLOT_TYPE_OFFSET 26 54 - #define SUPPORT_64B_MASK BIT(24) 55 - #define SUPPORT_64B_SHIFT 24 56 - #define SUPPORT_HS400_MASK BIT(2) 57 - #define SUPPORT_HS400_SHIFT 2 58 - #define SUPPORT_DDR50_MASK BIT(1) 59 - #define SUPPORT_DDR50_SHIFT 1 60 - #define SUPPORT_SDR104_MASK BIT(0) 61 - #define SUPPORT_SDR104_SHIFT 0 62 - 63 - /* PHY_CFG_0 bit fields */ 64 - #define SEL_DLY_TXCLK_MASK BIT(29) 65 - #define SEL_DLY_TXCLK_SHIFT 29 66 - #define SEL_DLY_RXCLK_MASK BIT(28) 67 - #define SEL_DLY_RXCLK_SHIFT 28 68 - 69 - #define OTAP_DLY_ENA_MASK BIT(27) 70 - #define OTAP_DLY_ENA_SHIFT 27 71 - #define OTAP_DLY_SEL_MASK GENMASK(26, 23) 72 - #define OTAP_DLY_SEL_SHIFT 23 73 - #define ITAP_CHG_WIN_MASK BIT(22) 74 - #define ITAP_CHG_WIN_SHIFT 22 75 - #define ITAP_DLY_ENA_MASK BIT(21) 76 - #define ITAP_DLY_ENA_SHIFT 21 77 - #define ITAP_DLY_SEL_MASK GENMASK(20, 16) 78 - #define ITAP_DLY_SEL_SHIFT 16 79 - #define RET_ENB_MASK BIT(15) 80 - #define RET_ENB_SHIFT 15 81 - #define RET_EN_MASK BIT(14) 82 - #define RET_EN_SHIFT 14 83 - #define DLL_IFF_MASK GENMASK(13, 11) 84 - #define DLL_IFF_SHIFT 11 85 - #define DLL_EN_MASK BIT(10) 86 - #define DLL_EN_SHIFT 10 87 - #define DLL_TRIM_ICP_MASK GENMASK(9, 6) 88 - #define DLL_TRIM_ICP_SHIFT 6 89 - #define RETRIM_EN_MASK BIT(5) 90 - #define RETRIM_EN_SHIFT 5 91 - #define RETRIM_MASK BIT(4) 92 - #define RETRIM_SHIFT 4 93 - #define DR_TY_MASK GENMASK(3, 1) 94 - #define DR_TY_SHIFT 1 95 - #define PWR_DOWN_MASK BIT(0) 96 - #define PWR_DOWN_SHIFT 0 97 - 98 - /* PHY_CFG_1 bit fields */ 99 - #define REN_DAT_MASK GENMASK(19, 12) 100 - #define REN_DAT_SHIFT 12 101 - #define REN_CMD_MASK BIT(11) 102 - #define REN_CMD_SHIFT 11 103 - #define REN_STRB_MASK BIT(10) 104 - #define REN_STRB_SHIFT 10 105 - #define PU_STRB_MASK BIT(20) 106 - #define PU_STRB_SHIFT 20 107 - 108 - /* PHY_CFG_2 bit fields */ 109 - #define CLKBUF_MASK GENMASK(24, 21) 110 - #define CLKBUF_SHIFT 21 111 - #define SEL_STRB_MASK GENMASK(20, 13) 112 - #define SEL_STRB_SHIFT 13 113 - #define SEL_FREQ_MASK GENMASK(12, 10) 114 - #define SEL_FREQ_SHIFT 10 115 - 116 - /* PHY_STAT bit fields */ 117 - #define CAL_DONE BIT(6) 118 - #define DLL_RDY BIT(5) 119 - 120 - #define OTAP_DLY 0x0 121 - #define ITAP_DLY 0x0 122 - #define STRB 0x33 123 - 124 - /* From ACS_eMMC51_16nFFC_RO1100_Userguide_v1p0.pdf p17 */ 125 - #define FREQSEL_200M_170M 0x0 126 - #define FREQSEL_170M_140M 0x1 127 - #define FREQSEL_140M_110M 0x2 128 - #define FREQSEL_110M_80M 0x3 129 - #define FREQSEL_80M_50M 0x4 130 - #define FREQSEL_275M_250M 0x5 131 - #define FREQSEL_250M_225M 0x6 132 - #define FREQSEL_225M_200M 0x7 133 - 134 - /* Phy power status */ 135 - #define PHY_UNINITIALIZED 0 136 - #define PHY_INITIALIZED 1 137 - 138 - /* 139 - * During init(400KHz) phy_settings will be called with 200MHZ clock 140 - * To avoid incorrectly setting the phy for init(400KHZ) "phy_power_sts" is used. 141 - * When actual clock is set always phy is powered off once and then powered on. 142 - * (sdhci_arasan_set_clock). That feature will be used to identify whether the 143 - * settings are for init phy_power_on or actual clock phy_power_on 144 - * 0 --> init settings 145 - * 1 --> actual settings 146 - */ 147 - 148 - struct thunderbay_emmc_phy { 149 - void __iomem *reg_base; 150 - struct clk *emmcclk; 151 - int phy_power_sts; 152 - }; 153 - 154 - static inline void update_reg(struct thunderbay_emmc_phy *tbh_phy, u32 offset, 155 - u32 mask, u32 shift, u32 val) 156 - { 157 - u32 tmp; 158 - 159 - tmp = readl(tbh_phy->reg_base + offset); 160 - tmp &= ~mask; 161 - tmp |= val << shift; 162 - writel(tmp, tbh_phy->reg_base + offset); 163 - } 164 - 165 - static int thunderbay_emmc_phy_power(struct phy *phy, bool power_on) 166 - { 167 - struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy); 168 - unsigned int freqsel = FREQSEL_200M_170M; 169 - unsigned long rate; 170 - static int lock; 171 - u32 val; 172 - int ret; 173 - 174 - /* Disable DLL */ 175 - rate = clk_get_rate(tbh_phy->emmcclk); 176 - switch (rate) { 177 - case 200000000: 178 - /* lock dll only when it is used, i.e only if SEL_DLY_TXCLK/RXCLK are 0 */ 179 - update_reg(tbh_phy, PHY_CFG_0, DLL_EN_MASK, DLL_EN_SHIFT, 0x0); 180 - break; 181 - 182 - /* dll lock not required for other frequencies */ 183 - case 50000000 ... 52000000: 184 - case 400000: 185 - default: 186 - break; 187 - } 188 - 189 - if (!power_on) 190 - return 0; 191 - 192 - rate = clk_get_rate(tbh_phy->emmcclk); 193 - switch (rate) { 194 - case 170000001 ... 200000000: 195 - freqsel = FREQSEL_200M_170M; 196 - break; 197 - 198 - case 140000001 ... 170000000: 199 - freqsel = FREQSEL_170M_140M; 200 - break; 201 - 202 - case 110000001 ... 140000000: 203 - freqsel = FREQSEL_140M_110M; 204 - break; 205 - 206 - case 80000001 ... 110000000: 207 - freqsel = FREQSEL_110M_80M; 208 - break; 209 - 210 - case 50000000 ... 80000000: 211 - freqsel = FREQSEL_80M_50M; 212 - break; 213 - 214 - case 250000001 ... 275000000: 215 - freqsel = FREQSEL_275M_250M; 216 - break; 217 - 218 - case 225000001 ... 250000000: 219 - freqsel = FREQSEL_250M_225M; 220 - break; 221 - 222 - case 200000001 ... 225000000: 223 - freqsel = FREQSEL_225M_200M; 224 - break; 225 - default: 226 - break; 227 - } 228 - /* Clock rate is checked against upper limit. It may fall low during init */ 229 - if (rate > 200000000) 230 - dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate); 231 - 232 - udelay(5); 233 - 234 - if (lock == 0) { 235 - /* PDB will be done only once per boot */ 236 - update_reg(tbh_phy, PHY_CFG_0, PWR_DOWN_MASK, 237 - PWR_DOWN_SHIFT, 0x1); 238 - lock = 1; 239 - /* 240 - * According to the user manual, it asks driver to wait 5us for 241 - * calpad busy trimming. However it is documented that this value is 242 - * PVT(A.K.A. process, voltage and temperature) relevant, so some 243 - * failure cases are found which indicates we should be more tolerant 244 - * to calpad busy trimming. 245 - */ 246 - ret = readl_poll_timeout(tbh_phy->reg_base + PHY_STAT, 247 - val, (val & CAL_DONE), 10, 50); 248 - if (ret) { 249 - dev_err(&phy->dev, "caldone failed, ret=%d\n", ret); 250 - return ret; 251 - } 252 - } 253 - rate = clk_get_rate(tbh_phy->emmcclk); 254 - switch (rate) { 255 - case 200000000: 256 - /* Set frequency of the DLL operation */ 257 - update_reg(tbh_phy, PHY_CFG_2, SEL_FREQ_MASK, SEL_FREQ_SHIFT, freqsel); 258 - 259 - /* Enable DLL */ 260 - update_reg(tbh_phy, PHY_CFG_0, DLL_EN_MASK, DLL_EN_SHIFT, 0x1); 261 - 262 - /* 263 - * After enabling analog DLL circuits docs say that we need 10.2 us if 264 - * our source clock is at 50 MHz and that lock time scales linearly 265 - * with clock speed. If we are powering on the PHY and the card clock 266 - * is super slow (like 100kHz) this could take as long as 5.1 ms as 267 - * per the math: 10.2 us * (50000000 Hz / 100000 Hz) => 5.1 ms 268 - * hopefully we won't be running at 100 kHz, but we should still make 269 - * sure we wait long enough. 270 - * 271 - * NOTE: There appear to be corner cases where the DLL seems to take 272 - * extra long to lock for reasons that aren't understood. In some 273 - * extreme cases we've seen it take up to over 10ms (!). We'll be 274 - * generous and give it 50ms. 275 - */ 276 - ret = readl_poll_timeout(tbh_phy->reg_base + PHY_STAT, 277 - val, (val & DLL_RDY), 10, 50 * USEC_PER_MSEC); 278 - if (ret) { 279 - dev_err(&phy->dev, "dllrdy failed, ret=%d\n", ret); 280 - return ret; 281 - } 282 - break; 283 - 284 - default: 285 - break; 286 - } 287 - return 0; 288 - } 289 - 290 - static int thunderbay_emmc_phy_init(struct phy *phy) 291 - { 292 - struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy); 293 - 294 - tbh_phy->emmcclk = clk_get(&phy->dev, "emmcclk"); 295 - 296 - return PTR_ERR_OR_ZERO(tbh_phy->emmcclk); 297 - } 298 - 299 - static int thunderbay_emmc_phy_exit(struct phy *phy) 300 - { 301 - struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy); 302 - 303 - clk_put(tbh_phy->emmcclk); 304 - 305 - return 0; 306 - } 307 - 308 - static int thunderbay_emmc_phy_power_on(struct phy *phy) 309 - { 310 - struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy); 311 - unsigned long rate; 312 - 313 - /* Overwrite capability bits configurable in bootloader */ 314 - update_reg(tbh_phy, CTRL_CFG_0, 315 - SUPPORT_HS_MASK, SUPPORT_HS_SHIFT, 0x1); 316 - update_reg(tbh_phy, CTRL_CFG_0, 317 - SUPPORT_8B_MASK, SUPPORT_8B_SHIFT, 0x1); 318 - update_reg(tbh_phy, CTRL_CFG_1, 319 - SUPPORT_SDR50_MASK, SUPPORT_SDR50_SHIFT, 0x1); 320 - update_reg(tbh_phy, CTRL_CFG_1, 321 - SUPPORT_DDR50_MASK, SUPPORT_DDR50_SHIFT, 0x1); 322 - update_reg(tbh_phy, CTRL_CFG_1, 323 - SUPPORT_SDR104_MASK, SUPPORT_SDR104_SHIFT, 0x1); 324 - update_reg(tbh_phy, CTRL_CFG_1, 325 - SUPPORT_HS400_MASK, SUPPORT_HS400_SHIFT, 0x1); 326 - update_reg(tbh_phy, CTRL_CFG_1, 327 - SUPPORT_64B_MASK, SUPPORT_64B_SHIFT, 0x1); 328 - 329 - if (tbh_phy->phy_power_sts == PHY_UNINITIALIZED) { 330 - /* Indicates initialization, settings for init, same as 400KHZ setting */ 331 - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, SEL_DLY_TXCLK_SHIFT, 0x1); 332 - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, SEL_DLY_RXCLK_SHIFT, 0x1); 333 - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, ITAP_DLY_ENA_SHIFT, 0x0); 334 - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, ITAP_DLY_SEL_SHIFT, 0x0); 335 - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, OTAP_DLY_ENA_SHIFT, 0x0); 336 - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, OTAP_DLY_SEL_SHIFT, 0); 337 - update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, DLL_TRIM_ICP_SHIFT, 0); 338 - update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, DR_TY_SHIFT, 0x1); 339 - 340 - } else if (tbh_phy->phy_power_sts == PHY_INITIALIZED) { 341 - /* Indicates actual clock setting */ 342 - rate = clk_get_rate(tbh_phy->emmcclk); 343 - switch (rate) { 344 - case 200000000: 345 - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, 346 - SEL_DLY_TXCLK_SHIFT, 0x0); 347 - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, 348 - SEL_DLY_RXCLK_SHIFT, 0x0); 349 - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, 350 - ITAP_DLY_ENA_SHIFT, 0x0); 351 - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, 352 - ITAP_DLY_SEL_SHIFT, 0x0); 353 - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, 354 - OTAP_DLY_ENA_SHIFT, 0x1); 355 - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, 356 - OTAP_DLY_SEL_SHIFT, 2); 357 - update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, 358 - DLL_TRIM_ICP_SHIFT, 0x8); 359 - update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, 360 - DR_TY_SHIFT, 0x1); 361 - /* For HS400 only */ 362 - update_reg(tbh_phy, PHY_CFG_2, SEL_STRB_MASK, 363 - SEL_STRB_SHIFT, STRB); 364 - break; 365 - 366 - case 50000000 ... 52000000: 367 - /* For both HS and DDR52 this setting works */ 368 - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, 369 - SEL_DLY_TXCLK_SHIFT, 0x1); 370 - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, 371 - SEL_DLY_RXCLK_SHIFT, 0x1); 372 - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, 373 - ITAP_DLY_ENA_SHIFT, 0x0); 374 - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, 375 - ITAP_DLY_SEL_SHIFT, 0x0); 376 - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, 377 - OTAP_DLY_ENA_SHIFT, 0x1); 378 - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, 379 - OTAP_DLY_SEL_SHIFT, 4); 380 - update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, 381 - DLL_TRIM_ICP_SHIFT, 0x8); 382 - update_reg(tbh_phy, PHY_CFG_0, 383 - DR_TY_MASK, DR_TY_SHIFT, 0x1); 384 - break; 385 - 386 - case 400000: 387 - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, 388 - SEL_DLY_TXCLK_SHIFT, 0x1); 389 - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, 390 - SEL_DLY_RXCLK_SHIFT, 0x1); 391 - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, 392 - ITAP_DLY_ENA_SHIFT, 0x0); 393 - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, 394 - ITAP_DLY_SEL_SHIFT, 0x0); 395 - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, 396 - OTAP_DLY_ENA_SHIFT, 0x0); 397 - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, 398 - OTAP_DLY_SEL_SHIFT, 0); 399 - update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, 400 - DLL_TRIM_ICP_SHIFT, 0); 401 - update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, DR_TY_SHIFT, 0x1); 402 - break; 403 - 404 - default: 405 - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, 406 - SEL_DLY_TXCLK_SHIFT, 0x1); 407 - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, 408 - SEL_DLY_RXCLK_SHIFT, 0x1); 409 - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, 410 - ITAP_DLY_ENA_SHIFT, 0x0); 411 - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, 412 - ITAP_DLY_SEL_SHIFT, 0x0); 413 - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, 414 - OTAP_DLY_ENA_SHIFT, 0x1); 415 - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, 416 - OTAP_DLY_SEL_SHIFT, 2); 417 - update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, 418 - DLL_TRIM_ICP_SHIFT, 0x8); 419 - update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, 420 - DR_TY_SHIFT, 0x1); 421 - break; 422 - } 423 - /* Reset, init seq called without phy_power_off, this indicates init seq */ 424 - tbh_phy->phy_power_sts = PHY_UNINITIALIZED; 425 - } 426 - 427 - update_reg(tbh_phy, PHY_CFG_0, RETRIM_EN_MASK, RETRIM_EN_SHIFT, 0x1); 428 - update_reg(tbh_phy, PHY_CFG_0, RETRIM_MASK, RETRIM_SHIFT, 0x0); 429 - 430 - return thunderbay_emmc_phy_power(phy, 1); 431 - } 432 - 433 - static int thunderbay_emmc_phy_power_off(struct phy *phy) 434 - { 435 - struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy); 436 - 437 - tbh_phy->phy_power_sts = PHY_INITIALIZED; 438 - 439 - return thunderbay_emmc_phy_power(phy, 0); 440 - } 441 - 442 - static const struct phy_ops thunderbay_emmc_phy_ops = { 443 - .init = thunderbay_emmc_phy_init, 444 - .exit = thunderbay_emmc_phy_exit, 445 - .power_on = thunderbay_emmc_phy_power_on, 446 - .power_off = thunderbay_emmc_phy_power_off, 447 - .owner = THIS_MODULE, 448 - }; 449 - 450 - static const struct of_device_id thunderbay_emmc_phy_of_match[] = { 451 - { .compatible = "intel,thunderbay-emmc-phy", 452 - (void *)&thunderbay_emmc_phy_ops }, 453 - {} 454 - }; 455 - MODULE_DEVICE_TABLE(of, thunderbay_emmc_phy_of_match); 456 - 457 - static int thunderbay_emmc_phy_probe(struct platform_device *pdev) 458 - { 459 - struct thunderbay_emmc_phy *tbh_phy; 460 - struct phy_provider *phy_provider; 461 - struct device *dev = &pdev->dev; 462 - const struct of_device_id *id; 463 - struct phy *generic_phy; 464 - struct resource *res; 465 - 466 - if (!dev->of_node) 467 - return -ENODEV; 468 - 469 - tbh_phy = devm_kzalloc(dev, sizeof(*tbh_phy), GFP_KERNEL); 470 - if (!tbh_phy) 471 - return -ENOMEM; 472 - 473 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 474 - tbh_phy->reg_base = devm_ioremap_resource(&pdev->dev, res); 475 - if (IS_ERR(tbh_phy->reg_base)) 476 - return PTR_ERR(tbh_phy->reg_base); 477 - 478 - tbh_phy->phy_power_sts = PHY_UNINITIALIZED; 479 - id = of_match_node(thunderbay_emmc_phy_of_match, pdev->dev.of_node); 480 - if (!id) { 481 - dev_err(dev, "failed to get match_node\n"); 482 - return -EINVAL; 483 - } 484 - 485 - generic_phy = devm_phy_create(dev, dev->of_node, id->data); 486 - if (IS_ERR(generic_phy)) { 487 - dev_err(dev, "failed to create PHY\n"); 488 - return PTR_ERR(generic_phy); 489 - } 490 - 491 - phy_set_drvdata(generic_phy, tbh_phy); 492 - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 493 - 494 - return PTR_ERR_OR_ZERO(phy_provider); 495 - } 496 - 497 - static struct platform_driver thunderbay_emmc_phy_driver = { 498 - .probe = thunderbay_emmc_phy_probe, 499 - .driver = { 500 - .name = "thunderbay-emmc-phy", 501 - .of_match_table = thunderbay_emmc_phy_of_match, 502 - }, 503 - }; 504 - module_platform_driver(thunderbay_emmc_phy_driver); 505 - 506 - MODULE_AUTHOR("Nandhini S <nandhini.srikandan@intel.com>"); 507 - MODULE_AUTHOR("Rashmi A <rashmi.a@intel.com>"); 508 - MODULE_DESCRIPTION("Intel Thunder Bay eMMC PHY driver"); 509 - MODULE_LICENSE("GPL v2");