612 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Copyright 2024 NXP4 */5 6#include <linux/bitfield.h>7#include <linux/clk.h>8#include <linux/delay.h>9#include <linux/io.h>10#include <linux/iopoll.h>11#include <linux/module.h>12#include <linux/of.h>13#include <linux/pci_regs.h>14#include <linux/phy/phy.h>15#include <linux/phy/pcie.h>16#include <linux/platform_device.h>17#include <linux/regmap.h>18 19#include <dt-bindings/phy/phy.h>20#include <dt-bindings/phy/phy-imx8-pcie.h>21 22#define MAX_NUM_LANE 323#define LANE_NUM_CLKS 524 25/* Parameters for the waiting for PCIe PHY PLL to lock */26#define PHY_INIT_WAIT_USLEEP_MAX 1027#define PHY_INIT_WAIT_TIMEOUT (1000 * PHY_INIT_WAIT_USLEEP_MAX)28 29/* i.MX8Q HSIO registers */30#define HSIO_CTRL0 0x031#define HSIO_APB_RSTN_0 BIT(0)32#define HSIO_APB_RSTN_1 BIT(1)33#define HSIO_PIPE_RSTN_0_MASK GENMASK(25, 24)34#define HSIO_PIPE_RSTN_1_MASK GENMASK(27, 26)35#define HSIO_MODE_MASK GENMASK(20, 17)36#define HSIO_MODE_PCIE 0x037#define HSIO_MODE_SATA 0x438#define HSIO_DEVICE_TYPE_MASK GENMASK(27, 24)39#define HSIO_EPCS_TXDEEMP BIT(5)40#define HSIO_EPCS_TXDEEMP_SEL BIT(6)41#define HSIO_EPCS_PHYRESET_N BIT(7)42#define HSIO_RESET_N BIT(12)43 44#define HSIO_IOB_RXENA BIT(0)45#define HSIO_IOB_TXENA BIT(1)46#define HSIO_IOB_A_0_TXOE BIT(2)47#define HSIO_IOB_A_0_M1M0_2 BIT(4)48#define HSIO_IOB_A_0_M1M0_MASK GENMASK(4, 3)49#define HSIO_PHYX1_EPCS_SEL BIT(12)50#define HSIO_PCIE_AB_SELECT BIT(13)51 52#define HSIO_PHY_STS0 0x453#define HSIO_LANE0_TX_PLL_LOCK BIT(4)54#define HSIO_LANE1_TX_PLL_LOCK BIT(12)55 56#define HSIO_CTRL2 0x857#define HSIO_LTSSM_ENABLE BIT(4)58#define HSIO_BUTTON_RST_N BIT(21)59#define HSIO_PERST_N BIT(22)60#define HSIO_POWER_UP_RST_N BIT(23)61 62#define HSIO_PCIE_STS0 0xc63#define HSIO_PM_REQ_CORE_RST BIT(19)64 65#define HSIO_REG48_PMA_STATUS 0x3066#define HSIO_REG48_PMA_RDY BIT(7)67 68struct imx_hsio_drvdata {69 int lane_num;70};71 72struct imx_hsio_lane {73 u32 ctrl_index;74 u32 ctrl_off;75 u32 idx;76 u32 phy_off;77 u32 phy_type;78 const char * const *clk_names;79 struct clk_bulk_data clks[LANE_NUM_CLKS];80 struct imx_hsio_priv *priv;81 struct phy *phy;82 enum phy_mode phy_mode;83};84 85struct imx_hsio_priv {86 void __iomem *base;87 struct device *dev;88 struct mutex lock;89 const char *hsio_cfg;90 const char *refclk_pad;91 u32 open_cnt;92 struct regmap *phy;93 struct regmap *ctrl;94 struct regmap *misc;95 const struct imx_hsio_drvdata *drvdata;96 struct imx_hsio_lane lane[MAX_NUM_LANE];97};98 99static const char * const lan0_pcie_clks[] = {"apb_pclk0", "pclk0", "ctl0_crr",100 "phy0_crr", "misc_crr"};101static const char * const lan1_pciea_clks[] = {"apb_pclk1", "pclk1", "ctl0_crr",102 "phy0_crr", "misc_crr"};103static const char * const lan1_pcieb_clks[] = {"apb_pclk1", "pclk1", "ctl1_crr",104 "phy0_crr", "misc_crr"};105static const char * const lan2_pcieb_clks[] = {"apb_pclk2", "pclk2", "ctl1_crr",106 "phy1_crr", "misc_crr"};107static const char * const lan2_sata_clks[] = {"pclk2", "epcs_tx", "epcs_rx",108 "phy1_crr", "misc_crr"};109 110static const struct regmap_config regmap_config = {111 .reg_bits = 32,112 .val_bits = 32,113 .reg_stride = 4,114};115 116static int imx_hsio_init(struct phy *phy)117{118 int ret, i;119 struct imx_hsio_lane *lane = phy_get_drvdata(phy);120 struct imx_hsio_priv *priv = lane->priv;121 struct device *dev = priv->dev;122 123 /* Assign clocks refer to different modes */124 switch (lane->phy_type) {125 case PHY_TYPE_PCIE:126 lane->phy_mode = PHY_MODE_PCIE;127 if (lane->ctrl_index == 0) { /* PCIEA */128 lane->ctrl_off = 0;129 lane->phy_off = 0;130 131 for (i = 0; i < LANE_NUM_CLKS; i++) {132 if (lane->idx == 0)133 lane->clks[i].id = lan0_pcie_clks[i];134 else135 lane->clks[i].id = lan1_pciea_clks[i];136 }137 } else { /* PCIEB */138 if (lane->idx == 0) { /* i.MX8QXP */139 lane->ctrl_off = 0;140 lane->phy_off = 0;141 } else {142 /*143 * On i.MX8QM, only second or third lane can be144 * bound to PCIEB.145 */146 lane->ctrl_off = SZ_64K;147 if (lane->idx == 1)148 lane->phy_off = 0;149 else /* the third lane is bound to PCIEB */150 lane->phy_off = SZ_64K;151 }152 153 for (i = 0; i < LANE_NUM_CLKS; i++) {154 if (lane->idx == 1)155 lane->clks[i].id = lan1_pcieb_clks[i];156 else if (lane->idx == 2)157 lane->clks[i].id = lan2_pcieb_clks[i];158 else /* i.MX8QXP only has PCIEB, idx is 0 */159 lane->clks[i].id = lan0_pcie_clks[i];160 }161 }162 break;163 case PHY_TYPE_SATA:164 /* On i.MX8QM, only the third lane can be bound to SATA */165 lane->phy_mode = PHY_MODE_SATA;166 lane->ctrl_off = SZ_128K;167 lane->phy_off = SZ_64K;168 169 for (i = 0; i < LANE_NUM_CLKS; i++)170 lane->clks[i].id = lan2_sata_clks[i];171 break;172 default:173 return -EINVAL;174 }175 176 /* Fetch clocks and enable them */177 ret = devm_clk_bulk_get(dev, LANE_NUM_CLKS, lane->clks);178 if (ret)179 return ret;180 ret = clk_bulk_prepare_enable(LANE_NUM_CLKS, lane->clks);181 if (ret)182 return ret;183 184 /* allow the clocks to stabilize */185 usleep_range(200, 500);186 return 0;187}188 189static int imx_hsio_exit(struct phy *phy)190{191 struct imx_hsio_lane *lane = phy_get_drvdata(phy);192 193 clk_bulk_disable_unprepare(LANE_NUM_CLKS, lane->clks);194 195 return 0;196}197 198static void imx_hsio_pcie_phy_resets(struct phy *phy)199{200 struct imx_hsio_lane *lane = phy_get_drvdata(phy);201 struct imx_hsio_priv *priv = lane->priv;202 203 regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2,204 HSIO_BUTTON_RST_N);205 regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2,206 HSIO_PERST_N);207 regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2,208 HSIO_POWER_UP_RST_N);209 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2,210 HSIO_BUTTON_RST_N);211 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2,212 HSIO_PERST_N);213 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2,214 HSIO_POWER_UP_RST_N);215 216 if (lane->idx == 1) {217 regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0,218 HSIO_APB_RSTN_1);219 regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0,220 HSIO_PIPE_RSTN_1_MASK);221 } else {222 regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0,223 HSIO_APB_RSTN_0);224 regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0,225 HSIO_PIPE_RSTN_0_MASK);226 }227}228 229static void imx_hsio_sata_phy_resets(struct phy *phy)230{231 struct imx_hsio_lane *lane = phy_get_drvdata(phy);232 struct imx_hsio_priv *priv = lane->priv;233 234 /* clear PHY RST, then set it */235 regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0,236 HSIO_EPCS_PHYRESET_N);237 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0,238 HSIO_EPCS_PHYRESET_N);239 240 /* CTRL RST: SET -> delay 1 us -> CLEAR -> SET */241 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0, HSIO_RESET_N);242 udelay(1);243 regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0,244 HSIO_RESET_N);245 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0, HSIO_RESET_N);246}247 248static void imx_hsio_configure_clk_pad(struct phy *phy)249{250 bool pll = false;251 struct imx_hsio_lane *lane = phy_get_drvdata(phy);252 struct imx_hsio_priv *priv = lane->priv;253 254 if (strncmp(priv->refclk_pad, "output", 6) == 0) {255 pll = true;256 regmap_update_bits(priv->misc, HSIO_CTRL0,257 HSIO_IOB_A_0_TXOE | HSIO_IOB_A_0_M1M0_MASK,258 HSIO_IOB_A_0_TXOE | HSIO_IOB_A_0_M1M0_2);259 } else {260 regmap_update_bits(priv->misc, HSIO_CTRL0,261 HSIO_IOB_A_0_TXOE | HSIO_IOB_A_0_M1M0_MASK,262 0);263 }264 265 regmap_update_bits(priv->misc, HSIO_CTRL0, HSIO_IOB_RXENA,266 pll ? 0 : HSIO_IOB_RXENA);267 regmap_update_bits(priv->misc, HSIO_CTRL0, HSIO_IOB_TXENA,268 pll ? HSIO_IOB_TXENA : 0);269}270 271static void imx_hsio_pre_set(struct phy *phy)272{273 struct imx_hsio_lane *lane = phy_get_drvdata(phy);274 struct imx_hsio_priv *priv = lane->priv;275 276 if (strncmp(priv->hsio_cfg, "pciea-x2-pcieb", 14) == 0) {277 regmap_set_bits(priv->misc, HSIO_CTRL0, HSIO_PCIE_AB_SELECT);278 } else if (strncmp(priv->hsio_cfg, "pciea-x2-sata", 13) == 0) {279 regmap_set_bits(priv->misc, HSIO_CTRL0, HSIO_PHYX1_EPCS_SEL);280 } else if (strncmp(priv->hsio_cfg, "pciea-pcieb-sata", 16) == 0) {281 regmap_set_bits(priv->misc, HSIO_CTRL0, HSIO_PCIE_AB_SELECT);282 regmap_set_bits(priv->misc, HSIO_CTRL0, HSIO_PHYX1_EPCS_SEL);283 }284 285 imx_hsio_configure_clk_pad(phy);286}287 288static int imx_hsio_pcie_power_on(struct phy *phy)289{290 int ret;291 u32 val, addr, cond;292 struct imx_hsio_lane *lane = phy_get_drvdata(phy);293 struct imx_hsio_priv *priv = lane->priv;294 295 imx_hsio_pcie_phy_resets(phy);296 297 /* Toggle apb_pclk to make sure PM_REQ_CORE_RST is cleared. */298 clk_disable_unprepare(lane->clks[0].clk);299 mdelay(1);300 ret = clk_prepare_enable(lane->clks[0].clk);301 if (ret) {302 dev_err(priv->dev, "unable to enable phy apb_pclk\n");303 return ret;304 }305 306 addr = lane->ctrl_off + HSIO_PCIE_STS0;307 cond = HSIO_PM_REQ_CORE_RST;308 ret = regmap_read_poll_timeout(priv->ctrl, addr, val,309 (val & cond) == 0,310 PHY_INIT_WAIT_USLEEP_MAX,311 PHY_INIT_WAIT_TIMEOUT);312 if (ret)313 dev_err(priv->dev, "HSIO_PM_REQ_CORE_RST is set\n");314 return ret;315}316 317static int imx_hsio_sata_power_on(struct phy *phy)318{319 int ret;320 u32 val, cond;321 struct imx_hsio_lane *lane = phy_get_drvdata(phy);322 struct imx_hsio_priv *priv = lane->priv;323 324 regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0, HSIO_APB_RSTN_0);325 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0,326 HSIO_EPCS_TXDEEMP);327 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0,328 HSIO_EPCS_TXDEEMP_SEL);329 330 imx_hsio_sata_phy_resets(phy);331 332 cond = HSIO_REG48_PMA_RDY;333 ret = read_poll_timeout(readb, val, ((val & cond) == cond),334 PHY_INIT_WAIT_USLEEP_MAX,335 PHY_INIT_WAIT_TIMEOUT, false,336 priv->base + HSIO_REG48_PMA_STATUS);337 if (ret)338 dev_err(priv->dev, "PHY calibration is timeout\n");339 else340 dev_dbg(priv->dev, "PHY calibration is done\n");341 342 return ret;343}344 345static int imx_hsio_power_on(struct phy *phy)346{347 int ret;348 u32 val, cond;349 struct imx_hsio_lane *lane = phy_get_drvdata(phy);350 struct imx_hsio_priv *priv = lane->priv;351 352 scoped_guard(mutex, &priv->lock) {353 if (!priv->open_cnt)354 imx_hsio_pre_set(phy);355 priv->open_cnt++;356 }357 358 if (lane->phy_mode == PHY_MODE_PCIE)359 ret = imx_hsio_pcie_power_on(phy);360 else /* SATA */361 ret = imx_hsio_sata_power_on(phy);362 if (ret)363 return ret;364 365 /* Polling to check the PHY is ready or not. */366 if (lane->idx == 1)367 cond = HSIO_LANE1_TX_PLL_LOCK;368 else369 /*370 * Except the phy_off, the bit-offset of lane2 is same to lane0.371 * Merge the lane0 and lane2 bit-operations together.372 */373 cond = HSIO_LANE0_TX_PLL_LOCK;374 375 ret = regmap_read_poll_timeout(priv->phy, lane->phy_off + HSIO_PHY_STS0,376 val, ((val & cond) == cond),377 PHY_INIT_WAIT_USLEEP_MAX,378 PHY_INIT_WAIT_TIMEOUT);379 if (ret) {380 dev_err(priv->dev, "IMX8Q PHY%d PLL lock timeout\n", lane->idx);381 return ret;382 }383 dev_dbg(priv->dev, "IMX8Q PHY%d PLL is locked\n", lane->idx);384 385 return ret;386}387 388static int imx_hsio_power_off(struct phy *phy)389{390 struct imx_hsio_lane *lane = phy_get_drvdata(phy);391 struct imx_hsio_priv *priv = lane->priv;392 393 scoped_guard(mutex, &priv->lock) {394 priv->open_cnt--;395 if (priv->open_cnt == 0) {396 regmap_clear_bits(priv->misc, HSIO_CTRL0,397 HSIO_PCIE_AB_SELECT);398 regmap_clear_bits(priv->misc, HSIO_CTRL0,399 HSIO_PHYX1_EPCS_SEL);400 401 if (lane->phy_mode == PHY_MODE_PCIE) {402 regmap_clear_bits(priv->ctrl,403 lane->ctrl_off + HSIO_CTRL2,404 HSIO_BUTTON_RST_N);405 regmap_clear_bits(priv->ctrl,406 lane->ctrl_off + HSIO_CTRL2,407 HSIO_PERST_N);408 regmap_clear_bits(priv->ctrl,409 lane->ctrl_off + HSIO_CTRL2,410 HSIO_POWER_UP_RST_N);411 } else {412 regmap_clear_bits(priv->ctrl,413 lane->ctrl_off + HSIO_CTRL0,414 HSIO_EPCS_TXDEEMP);415 regmap_clear_bits(priv->ctrl,416 lane->ctrl_off + HSIO_CTRL0,417 HSIO_EPCS_TXDEEMP_SEL);418 regmap_clear_bits(priv->ctrl,419 lane->ctrl_off + HSIO_CTRL0,420 HSIO_RESET_N);421 }422 423 if (lane->idx == 1) {424 regmap_clear_bits(priv->phy,425 lane->phy_off + HSIO_CTRL0,426 HSIO_APB_RSTN_1);427 regmap_clear_bits(priv->phy,428 lane->phy_off + HSIO_CTRL0,429 HSIO_PIPE_RSTN_1_MASK);430 } else {431 /*432 * Except the phy_off, the bit-offset of lane2 is same433 * to lane0. Merge the lane0 and lane2 bit-operations434 * together.435 */436 regmap_clear_bits(priv->phy,437 lane->phy_off + HSIO_CTRL0,438 HSIO_APB_RSTN_0);439 regmap_clear_bits(priv->phy,440 lane->phy_off + HSIO_CTRL0,441 HSIO_PIPE_RSTN_0_MASK);442 }443 }444 }445 446 return 0;447}448 449static int imx_hsio_set_mode(struct phy *phy, enum phy_mode mode,450 int submode)451{452 u32 val;453 struct imx_hsio_lane *lane = phy_get_drvdata(phy);454 struct imx_hsio_priv *priv = lane->priv;455 456 if (lane->phy_mode != mode)457 return -EINVAL;458 459 val = (mode == PHY_MODE_PCIE) ? HSIO_MODE_PCIE : HSIO_MODE_SATA;460 val = FIELD_PREP(HSIO_MODE_MASK, val);461 regmap_update_bits(priv->phy, lane->phy_off + HSIO_CTRL0,462 HSIO_MODE_MASK, val);463 464 switch (submode) {465 case PHY_MODE_PCIE_RC:466 val = FIELD_PREP(HSIO_DEVICE_TYPE_MASK, PCI_EXP_TYPE_ROOT_PORT);467 break;468 case PHY_MODE_PCIE_EP:469 val = FIELD_PREP(HSIO_DEVICE_TYPE_MASK, PCI_EXP_TYPE_ENDPOINT);470 break;471 default: /* Support only PCIe EP and RC now. */472 return 0;473 }474 if (submode)475 regmap_update_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0,476 HSIO_DEVICE_TYPE_MASK, val);477 478 return 0;479}480 481static int imx_hsio_set_speed(struct phy *phy, int speed)482{483 struct imx_hsio_lane *lane = phy_get_drvdata(phy);484 struct imx_hsio_priv *priv = lane->priv;485 486 regmap_update_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2,487 HSIO_LTSSM_ENABLE,488 speed ? HSIO_LTSSM_ENABLE : 0);489 return 0;490}491 492static const struct phy_ops imx_hsio_ops = {493 .init = imx_hsio_init,494 .exit = imx_hsio_exit,495 .power_on = imx_hsio_power_on,496 .power_off = imx_hsio_power_off,497 .set_mode = imx_hsio_set_mode,498 .set_speed = imx_hsio_set_speed,499 .owner = THIS_MODULE,500};501 502static const struct imx_hsio_drvdata imx8qxp_hsio_drvdata = {503 .lane_num = 0x1,504};505 506static const struct imx_hsio_drvdata imx8qm_hsio_drvdata = {507 .lane_num = 0x3,508};509 510static const struct of_device_id imx_hsio_of_match[] = {511 {.compatible = "fsl,imx8qm-hsio", .data = &imx8qm_hsio_drvdata},512 {.compatible = "fsl,imx8qxp-hsio", .data = &imx8qxp_hsio_drvdata},513 { },514};515MODULE_DEVICE_TABLE(of, imx_hsio_of_match);516 517static struct phy *imx_hsio_xlate(struct device *dev,518 const struct of_phandle_args *args)519{520 struct imx_hsio_priv *priv = dev_get_drvdata(dev);521 int idx = args->args[0];522 int phy_type = args->args[1];523 int ctrl_index = args->args[2];524 525 if (idx < 0 || idx >= priv->drvdata->lane_num)526 return ERR_PTR(-EINVAL);527 priv->lane[idx].idx = idx;528 priv->lane[idx].phy_type = phy_type;529 priv->lane[idx].ctrl_index = ctrl_index;530 531 return priv->lane[idx].phy;532}533 534static int imx_hsio_probe(struct platform_device *pdev)535{536 int i;537 void __iomem *off;538 struct device *dev = &pdev->dev;539 struct device_node *np = dev->of_node;540 struct imx_hsio_priv *priv;541 struct phy_provider *provider;542 543 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);544 if (!priv)545 return -ENOMEM;546 priv->dev = &pdev->dev;547 priv->drvdata = of_device_get_match_data(dev);548 549 /* Get HSIO configuration mode */550 if (of_property_read_string(np, "fsl,hsio-cfg", &priv->hsio_cfg))551 priv->hsio_cfg = "pciea-pcieb-sata";552 /* Get PHY refclk pad mode */553 if (of_property_read_string(np, "fsl,refclk-pad-mode",554 &priv->refclk_pad))555 priv->refclk_pad = NULL;556 557 priv->base = devm_platform_ioremap_resource(pdev, 0);558 if (IS_ERR(priv->base))559 return PTR_ERR(priv->base);560 561 off = devm_platform_ioremap_resource_byname(pdev, "phy");562 priv->phy = devm_regmap_init_mmio(dev, off, ®map_config);563 if (IS_ERR(priv->phy))564 return dev_err_probe(dev, PTR_ERR(priv->phy),565 "unable to find phy csr registers\n");566 567 off = devm_platform_ioremap_resource_byname(pdev, "ctrl");568 priv->ctrl = devm_regmap_init_mmio(dev, off, ®map_config);569 if (IS_ERR(priv->ctrl))570 return dev_err_probe(dev, PTR_ERR(priv->ctrl),571 "unable to find ctrl csr registers\n");572 573 off = devm_platform_ioremap_resource_byname(pdev, "misc");574 priv->misc = devm_regmap_init_mmio(dev, off, ®map_config);575 if (IS_ERR(priv->misc))576 return dev_err_probe(dev, PTR_ERR(priv->misc),577 "unable to find misc csr registers\n");578 579 for (i = 0; i < priv->drvdata->lane_num; i++) {580 struct imx_hsio_lane *lane = &priv->lane[i];581 struct phy *phy;582 583 phy = devm_phy_create(&pdev->dev, NULL, &imx_hsio_ops);584 if (IS_ERR(phy))585 return PTR_ERR(phy);586 587 lane->priv = priv;588 lane->phy = phy;589 lane->idx = i;590 phy_set_drvdata(phy, lane);591 }592 593 dev_set_drvdata(dev, priv);594 dev_set_drvdata(&pdev->dev, priv);595 596 provider = devm_of_phy_provider_register(&pdev->dev, imx_hsio_xlate);597 598 return PTR_ERR_OR_ZERO(provider);599}600 601static struct platform_driver imx_hsio_driver = {602 .probe = imx_hsio_probe,603 .driver = {604 .name = "imx8qm-hsio-phy",605 .of_match_table = imx_hsio_of_match,606 }607};608module_platform_driver(imx_hsio_driver);609 610MODULE_DESCRIPTION("FSL IMX8QM HSIO SERDES PHY driver");611MODULE_LICENSE("GPL");612