790-12-v6.4-net-dsa-mt7530-introduce-separate-MDIO-driver.patch 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. From 5313432ca1e1a0677ad7b4f17a7e0186473f47aa Mon Sep 17 00:00:00 2001
  2. From: Daniel Golle <[email protected]>
  3. Date: Mon, 3 Apr 2023 02:19:13 +0100
  4. Subject: [PATCH 12/48] net: dsa: mt7530: introduce separate MDIO driver
  5. Split MT7530 switch driver into a common part and a part specific
  6. for MDIO connected switches and multi-chip modules.
  7. Move MDIO-specific functions to newly introduced mt7530-mdio.c while
  8. keeping the common parts in mt7530.c.
  9. Introduce new Kconfig symbol CONFIG_NET_DSA_MT7530_MDIO which is
  10. implied by CONFIG_NET_DSA_MT7530.
  11. Signed-off-by: Daniel Golle <[email protected]>
  12. Reviewed-by: Andrew Lunn <[email protected]>
  13. Signed-off-by: David S. Miller <[email protected]>
  14. ---
  15. MAINTAINERS | 1 +
  16. drivers/net/dsa/Kconfig | 18 ++-
  17. drivers/net/dsa/Makefile | 1 +
  18. drivers/net/dsa/mt7530-mdio.c | 271 ++++++++++++++++++++++++++++++++++
  19. drivers/net/dsa/mt7530.c | 264 +--------------------------------
  20. drivers/net/dsa/mt7530.h | 6 +
  21. 6 files changed, 302 insertions(+), 259 deletions(-)
  22. create mode 100644 drivers/net/dsa/mt7530-mdio.c
  23. --- a/MAINTAINERS
  24. +++ b/MAINTAINERS
  25. @@ -13069,6 +13069,7 @@ M: Landen Chao <[email protected]
  26. M: DENG Qingfang <[email protected]>
  27. L: [email protected]
  28. S: Maintained
  29. +F: drivers/net/dsa/mt7530-mdio.c
  30. F: drivers/net/dsa/mt7530.*
  31. F: net/dsa/tag_mtk.c
  32. --- a/drivers/net/dsa/Kconfig
  33. +++ b/drivers/net/dsa/Kconfig
  34. @@ -34,13 +34,25 @@ config NET_DSA_LANTIQ_GSWIP
  35. the xrx200 / VR9 SoC.
  36. config NET_DSA_MT7530
  37. - tristate "MediaTek MT753x and MT7621 Ethernet switch support"
  38. + tristate "MediaTek MT7530 and MT7531 Ethernet switch support"
  39. select NET_DSA_TAG_MTK
  40. + imply NET_DSA_MT7530_MDIO
  41. + help
  42. + This enables support for the MediaTek MT7530 and MT7531 Ethernet
  43. + switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
  44. + MT7621ST and MT7623AI SoCs, and built-in switch in MT7988 SoC are
  45. + supported as well.
  46. +
  47. +config NET_DSA_MT7530_MDIO
  48. + tristate "MediaTek MT7530 MDIO interface driver"
  49. + depends on NET_DSA_MT7530
  50. select MEDIATEK_GE_PHY
  51. select PCS_MTK_LYNXI
  52. help
  53. - This enables support for the MediaTek MT7530, MT7531, and MT7621
  54. - Ethernet switch chips.
  55. + This enables support for the MediaTek MT7530 and MT7531 switch
  56. + chips which are connected via MDIO, as well as multi-chip
  57. + module MT7530 which can be found in the MT7621AT, MT7621DAT,
  58. + MT7621ST and MT7623AI SoCs.
  59. config NET_DSA_MV88E6060
  60. tristate "Marvell 88E6060 ethernet switch chip support"
  61. --- a/drivers/net/dsa/Makefile
  62. +++ b/drivers/net/dsa/Makefile
  63. @@ -7,6 +7,7 @@ obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdi
  64. endif
  65. obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
  66. obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
  67. +obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
  68. obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
  69. obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o
  70. obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
  71. --- /dev/null
  72. +++ b/drivers/net/dsa/mt7530-mdio.c
  73. @@ -0,0 +1,271 @@
  74. +// SPDX-License-Identifier: GPL-2.0-only
  75. +
  76. +#include <linux/gpio/consumer.h>
  77. +#include <linux/mdio.h>
  78. +#include <linux/module.h>
  79. +#include <linux/pcs/pcs-mtk-lynxi.h>
  80. +#include <linux/of_irq.h>
  81. +#include <linux/of_mdio.h>
  82. +#include <linux/of_net.h>
  83. +#include <linux/of_platform.h>
  84. +#include <linux/regmap.h>
  85. +#include <linux/reset.h>
  86. +#include <linux/regulator/consumer.h>
  87. +#include <net/dsa.h>
  88. +
  89. +#include "mt7530.h"
  90. +
  91. +static int
  92. +mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
  93. +{
  94. + struct mii_bus *bus = context;
  95. + u16 page, r, lo, hi;
  96. + int ret;
  97. +
  98. + page = (reg >> 6) & 0x3ff;
  99. + r = (reg >> 2) & 0xf;
  100. + lo = val & 0xffff;
  101. + hi = val >> 16;
  102. +
  103. + /* MT7530 uses 31 as the pseudo port */
  104. + ret = bus->write(bus, 0x1f, 0x1f, page);
  105. + if (ret < 0)
  106. + return ret;
  107. +
  108. + ret = bus->write(bus, 0x1f, r, lo);
  109. + if (ret < 0)
  110. + return ret;
  111. +
  112. + ret = bus->write(bus, 0x1f, 0x10, hi);
  113. + return ret;
  114. +}
  115. +
  116. +static int
  117. +mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
  118. +{
  119. + struct mii_bus *bus = context;
  120. + u16 page, r, lo, hi;
  121. + int ret;
  122. +
  123. + page = (reg >> 6) & 0x3ff;
  124. + r = (reg >> 2) & 0xf;
  125. +
  126. + /* MT7530 uses 31 as the pseudo port */
  127. + ret = bus->write(bus, 0x1f, 0x1f, page);
  128. + if (ret < 0)
  129. + return ret;
  130. +
  131. + lo = bus->read(bus, 0x1f, r);
  132. + hi = bus->read(bus, 0x1f, 0x10);
  133. +
  134. + *val = (hi << 16) | (lo & 0xffff);
  135. +
  136. + return 0;
  137. +}
  138. +
  139. +static void
  140. +mt7530_mdio_regmap_lock(void *mdio_lock)
  141. +{
  142. + mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
  143. +}
  144. +
  145. +static void
  146. +mt7530_mdio_regmap_unlock(void *mdio_lock)
  147. +{
  148. + mutex_unlock(mdio_lock);
  149. +}
  150. +
  151. +static const struct regmap_bus mt7530_regmap_bus = {
  152. + .reg_write = mt7530_regmap_write,
  153. + .reg_read = mt7530_regmap_read,
  154. +};
  155. +
  156. +static int
  157. +mt7531_create_sgmii(struct mt7530_priv *priv)
  158. +{
  159. + struct regmap_config *mt7531_pcs_config[2];
  160. + struct phylink_pcs *pcs;
  161. + struct regmap *regmap;
  162. + int i, ret = 0;
  163. +
  164. + for (i = 0; i < 2; i++) {
  165. + mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
  166. + sizeof(struct regmap_config),
  167. + GFP_KERNEL);
  168. + if (!mt7531_pcs_config[i]) {
  169. + ret = -ENOMEM;
  170. + break;
  171. + }
  172. +
  173. + mt7531_pcs_config[i]->name = i ? "port6" : "port5";
  174. + mt7531_pcs_config[i]->reg_bits = 16;
  175. + mt7531_pcs_config[i]->val_bits = 32;
  176. + mt7531_pcs_config[i]->reg_stride = 4;
  177. + mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
  178. + mt7531_pcs_config[i]->max_register = 0x17c;
  179. + mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
  180. + mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
  181. + mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
  182. +
  183. + regmap = devm_regmap_init(priv->dev,
  184. + &mt7530_regmap_bus, priv->bus,
  185. + mt7531_pcs_config[i]);
  186. + if (IS_ERR(regmap)) {
  187. + ret = PTR_ERR(regmap);
  188. + break;
  189. + }
  190. + pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
  191. + MT7531_PHYA_CTRL_SIGNAL3, 0);
  192. + if (!pcs) {
  193. + ret = -ENXIO;
  194. + break;
  195. + }
  196. + priv->ports[5 + i].sgmii_pcs = pcs;
  197. + }
  198. +
  199. + if (ret && i)
  200. + mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
  201. +
  202. + return ret;
  203. +}
  204. +
  205. +static const struct of_device_id mt7530_of_match[] = {
  206. + { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
  207. + { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
  208. + { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
  209. + { /* sentinel */ },
  210. +};
  211. +MODULE_DEVICE_TABLE(of, mt7530_of_match);
  212. +
  213. +static int
  214. +mt7530_probe(struct mdio_device *mdiodev)
  215. +{
  216. + static struct regmap_config *regmap_config;
  217. + struct mt7530_priv *priv;
  218. + struct device_node *dn;
  219. + int ret;
  220. +
  221. + dn = mdiodev->dev.of_node;
  222. +
  223. + priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
  224. + if (!priv)
  225. + return -ENOMEM;
  226. +
  227. + priv->bus = mdiodev->bus;
  228. + priv->dev = &mdiodev->dev;
  229. +
  230. + ret = mt7530_probe_common(priv);
  231. + if (ret)
  232. + return ret;
  233. +
  234. + /* Use medatek,mcm property to distinguish hardware type that would
  235. + * cause a little bit differences on power-on sequence.
  236. + * Not MCM that indicates switch works as the remote standalone
  237. + * integrated circuit so the GPIO pin would be used to complete
  238. + * the reset, otherwise memory-mapped register accessing used
  239. + * through syscon provides in the case of MCM.
  240. + */
  241. + priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
  242. + if (priv->mcm) {
  243. + dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
  244. +
  245. + priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
  246. + if (IS_ERR(priv->rstc)) {
  247. + dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
  248. + return PTR_ERR(priv->rstc);
  249. + }
  250. + } else {
  251. + priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
  252. + GPIOD_OUT_LOW);
  253. + if (IS_ERR(priv->reset)) {
  254. + dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
  255. + return PTR_ERR(priv->reset);
  256. + }
  257. + }
  258. +
  259. + if (priv->id == ID_MT7530) {
  260. + priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
  261. + if (IS_ERR(priv->core_pwr))
  262. + return PTR_ERR(priv->core_pwr);
  263. +
  264. + priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
  265. + if (IS_ERR(priv->io_pwr))
  266. + return PTR_ERR(priv->io_pwr);
  267. + }
  268. +
  269. + regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
  270. + GFP_KERNEL);
  271. + if (!regmap_config)
  272. + return -ENOMEM;
  273. +
  274. + regmap_config->reg_bits = 16;
  275. + regmap_config->val_bits = 32;
  276. + regmap_config->reg_stride = 4;
  277. + regmap_config->max_register = MT7530_CREV;
  278. + regmap_config->disable_locking = true;
  279. + priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
  280. + priv->bus, regmap_config);
  281. + if (IS_ERR(priv->regmap))
  282. + return PTR_ERR(priv->regmap);
  283. +
  284. + if (priv->id == ID_MT7531) {
  285. + ret = mt7531_create_sgmii(priv);
  286. + if (ret)
  287. + return ret;
  288. + }
  289. +
  290. + return dsa_register_switch(priv->ds);
  291. +}
  292. +
  293. +static void
  294. +mt7530_remove(struct mdio_device *mdiodev)
  295. +{
  296. + struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
  297. + int ret = 0, i;
  298. +
  299. + if (!priv)
  300. + return;
  301. +
  302. + ret = regulator_disable(priv->core_pwr);
  303. + if (ret < 0)
  304. + dev_err(priv->dev,
  305. + "Failed to disable core power: %d\n", ret);
  306. +
  307. + ret = regulator_disable(priv->io_pwr);
  308. + if (ret < 0)
  309. + dev_err(priv->dev, "Failed to disable io pwr: %d\n",
  310. + ret);
  311. +
  312. + mt7530_remove_common(priv);
  313. +
  314. + for (i = 0; i < 2; ++i)
  315. + mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
  316. +}
  317. +
  318. +static void mt7530_shutdown(struct mdio_device *mdiodev)
  319. +{
  320. + struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
  321. +
  322. + if (!priv)
  323. + return;
  324. +
  325. + dsa_switch_shutdown(priv->ds);
  326. +
  327. + dev_set_drvdata(&mdiodev->dev, NULL);
  328. +}
  329. +
  330. +static struct mdio_driver mt7530_mdio_driver = {
  331. + .probe = mt7530_probe,
  332. + .remove = mt7530_remove,
  333. + .shutdown = mt7530_shutdown,
  334. + .mdiodrv.driver = {
  335. + .name = "mt7530-mdio",
  336. + .of_match_table = mt7530_of_match,
  337. + },
  338. +};
  339. +
  340. +mdio_module_driver(mt7530_mdio_driver);
  341. +
  342. +MODULE_AUTHOR("Sean Wang <[email protected]>");
  343. +MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MDIO)");
  344. +MODULE_LICENSE("GPL");
  345. --- a/drivers/net/dsa/mt7530.c
  346. +++ b/drivers/net/dsa/mt7530.c
  347. @@ -14,7 +14,6 @@
  348. #include <linux/of_mdio.h>
  349. #include <linux/of_net.h>
  350. #include <linux/of_platform.h>
  351. -#include <linux/pcs/pcs-mtk-lynxi.h>
  352. #include <linux/phylink.h>
  353. #include <linux/regmap.h>
  354. #include <linux/regulator/consumer.h>
  355. @@ -192,31 +191,6 @@ core_clear(struct mt7530_priv *priv, u32
  356. }
  357. static int
  358. -mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
  359. -{
  360. - struct mii_bus *bus = context;
  361. - u16 page, r, lo, hi;
  362. - int ret;
  363. -
  364. - page = (reg >> 6) & 0x3ff;
  365. - r = (reg >> 2) & 0xf;
  366. - lo = val & 0xffff;
  367. - hi = val >> 16;
  368. -
  369. - /* MT7530 uses 31 as the pseudo port */
  370. - ret = bus->write(bus, 0x1f, 0x1f, page);
  371. - if (ret < 0)
  372. - return ret;
  373. -
  374. - ret = bus->write(bus, 0x1f, r, lo);
  375. - if (ret < 0)
  376. - return ret;
  377. -
  378. - ret = bus->write(bus, 0x1f, 0x10, hi);
  379. - return ret;
  380. -}
  381. -
  382. -static int
  383. mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
  384. {
  385. int ret;
  386. @@ -230,29 +204,6 @@ mt7530_mii_write(struct mt7530_priv *pri
  387. return ret;
  388. }
  389. -static int
  390. -mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
  391. -{
  392. - struct mii_bus *bus = context;
  393. - u16 page, r, lo, hi;
  394. - int ret;
  395. -
  396. - page = (reg >> 6) & 0x3ff;
  397. - r = (reg >> 2) & 0xf;
  398. -
  399. - /* MT7530 uses 31 as the pseudo port */
  400. - ret = bus->write(bus, 0x1f, 0x1f, page);
  401. - if (ret < 0)
  402. - return ret;
  403. -
  404. - lo = bus->read(bus, 0x1f, r);
  405. - hi = bus->read(bus, 0x1f, 0x10);
  406. -
  407. - *val = (hi << 16) | (lo & 0xffff);
  408. -
  409. - return 0;
  410. -}
  411. -
  412. static u32
  413. mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
  414. {
  415. @@ -3008,72 +2959,6 @@ static const struct phylink_pcs_ops mt75
  416. .pcs_an_restart = mt7530_pcs_an_restart,
  417. };
  418. -static void
  419. -mt7530_mdio_regmap_lock(void *mdio_lock)
  420. -{
  421. - mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
  422. -}
  423. -
  424. -static void
  425. -mt7530_mdio_regmap_unlock(void *mdio_lock)
  426. -{
  427. - mutex_unlock(mdio_lock);
  428. -}
  429. -
  430. -static const struct regmap_bus mt7530_regmap_bus = {
  431. - .reg_write = mt7530_regmap_write,
  432. - .reg_read = mt7530_regmap_read,
  433. -};
  434. -
  435. -static int
  436. -mt7531_create_sgmii(struct mt7530_priv *priv)
  437. -{
  438. - struct regmap_config *mt7531_pcs_config[2];
  439. - struct phylink_pcs *pcs;
  440. - struct regmap *regmap;
  441. - int i, ret = 0;
  442. -
  443. - for (i = 0; i < 2; i++) {
  444. - mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
  445. - sizeof(struct regmap_config),
  446. - GFP_KERNEL);
  447. - if (!mt7531_pcs_config[i]) {
  448. - ret = -ENOMEM;
  449. - break;
  450. - }
  451. -
  452. - mt7531_pcs_config[i]->name = i ? "port6" : "port5";
  453. - mt7531_pcs_config[i]->reg_bits = 16;
  454. - mt7531_pcs_config[i]->val_bits = 32;
  455. - mt7531_pcs_config[i]->reg_stride = 4;
  456. - mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
  457. - mt7531_pcs_config[i]->max_register = 0x17c;
  458. - mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
  459. - mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
  460. - mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
  461. -
  462. - regmap = devm_regmap_init(priv->dev,
  463. - &mt7530_regmap_bus, priv->bus,
  464. - mt7531_pcs_config[i]);
  465. - if (IS_ERR(regmap)) {
  466. - ret = PTR_ERR(regmap);
  467. - break;
  468. - }
  469. - pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
  470. - MT7531_PHYA_CTRL_SIGNAL3, 0);
  471. - if (!pcs) {
  472. - ret = -ENXIO;
  473. - break;
  474. - }
  475. - priv->ports[5 + i].sgmii_pcs = pcs;
  476. - }
  477. -
  478. - if (ret && i)
  479. - mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
  480. -
  481. - return ret;
  482. -}
  483. -
  484. static int
  485. mt753x_setup(struct dsa_switch *ds)
  486. {
  487. @@ -3132,7 +3017,7 @@ static int mt753x_set_mac_eee(struct dsa
  488. return 0;
  489. }
  490. -static const struct dsa_switch_ops mt7530_switch_ops = {
  491. +const struct dsa_switch_ops mt7530_switch_ops = {
  492. .get_tag_protocol = mtk_get_tag_protocol,
  493. .setup = mt753x_setup,
  494. .get_strings = mt7530_get_strings,
  495. @@ -3166,8 +3051,9 @@ static const struct dsa_switch_ops mt753
  496. .get_mac_eee = mt753x_get_mac_eee,
  497. .set_mac_eee = mt753x_set_mac_eee,
  498. };
  499. +EXPORT_SYMBOL_GPL(mt7530_switch_ops);
  500. -static const struct mt753x_info mt753x_table[] = {
  501. +const struct mt753x_info mt753x_table[] = {
  502. [ID_MT7621] = {
  503. .id = ID_MT7621,
  504. .pcs_ops = &mt7530_pcs_ops,
  505. @@ -3200,16 +3086,9 @@ static const struct mt753x_info mt753x_t
  506. .mac_port_config = mt7531_mac_config,
  507. },
  508. };
  509. +EXPORT_SYMBOL_GPL(mt753x_table);
  510. -static const struct of_device_id mt7530_of_match[] = {
  511. - { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
  512. - { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
  513. - { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
  514. - { /* sentinel */ },
  515. -};
  516. -MODULE_DEVICE_TABLE(of, mt7530_of_match);
  517. -
  518. -static int
  519. +int
  520. mt7530_probe_common(struct mt7530_priv *priv)
  521. {
  522. struct device *dev = priv->dev;
  523. @@ -3246,88 +3125,9 @@ mt7530_probe_common(struct mt7530_priv *
  524. return 0;
  525. }
  526. +EXPORT_SYMBOL_GPL(mt7530_probe_common);
  527. -static int
  528. -mt7530_probe(struct mdio_device *mdiodev)
  529. -{
  530. - static struct regmap_config *regmap_config;
  531. - struct mt7530_priv *priv;
  532. - struct device_node *dn;
  533. - int ret;
  534. -
  535. - dn = mdiodev->dev.of_node;
  536. -
  537. - priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
  538. - if (!priv)
  539. - return -ENOMEM;
  540. -
  541. - priv->bus = mdiodev->bus;
  542. - priv->dev = &mdiodev->dev;
  543. -
  544. - ret = mt7530_probe_common(priv);
  545. - if (ret)
  546. - return ret;
  547. -
  548. - /* Use medatek,mcm property to distinguish hardware type that would
  549. - * cause a little bit differences on power-on sequence.
  550. - * Not MCM that indicates switch works as the remote standalone
  551. - * integrated circuit so the GPIO pin would be used to complete
  552. - * the reset, otherwise memory-mapped register accessing used
  553. - * through syscon provides in the case of MCM.
  554. - */
  555. - priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
  556. - if (priv->mcm) {
  557. - dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
  558. -
  559. - priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
  560. - if (IS_ERR(priv->rstc)) {
  561. - dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
  562. - return PTR_ERR(priv->rstc);
  563. - }
  564. - } else {
  565. - priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
  566. - GPIOD_OUT_LOW);
  567. - if (IS_ERR(priv->reset)) {
  568. - dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
  569. - return PTR_ERR(priv->reset);
  570. - }
  571. - }
  572. -
  573. - if (priv->id == ID_MT7530) {
  574. - priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
  575. - if (IS_ERR(priv->core_pwr))
  576. - return PTR_ERR(priv->core_pwr);
  577. -
  578. - priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
  579. - if (IS_ERR(priv->io_pwr))
  580. - return PTR_ERR(priv->io_pwr);
  581. - }
  582. -
  583. - regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
  584. - GFP_KERNEL);
  585. - if (!regmap_config)
  586. - return -ENOMEM;
  587. -
  588. - regmap_config->reg_bits = 16;
  589. - regmap_config->val_bits = 32;
  590. - regmap_config->reg_stride = 4;
  591. - regmap_config->max_register = MT7530_CREV;
  592. - regmap_config->disable_locking = true;
  593. - priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
  594. - priv->bus, regmap_config);
  595. - if (IS_ERR(priv->regmap))
  596. - return PTR_ERR(priv->regmap);
  597. -
  598. - if (priv->id == ID_MT7531) {
  599. - ret = mt7531_create_sgmii(priv);
  600. - if (ret)
  601. - return ret;
  602. - }
  603. -
  604. - return dsa_register_switch(priv->ds);
  605. -}
  606. -
  607. -static void
  608. +void
  609. mt7530_remove_common(struct mt7530_priv *priv)
  610. {
  611. if (priv->irq)
  612. @@ -3337,55 +3137,7 @@ mt7530_remove_common(struct mt7530_priv
  613. mutex_destroy(&priv->reg_mutex);
  614. }
  615. -
  616. -static void
  617. -mt7530_remove(struct mdio_device *mdiodev)
  618. -{
  619. - struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
  620. - int ret = 0, i;
  621. -
  622. - if (!priv)
  623. - return;
  624. -
  625. - ret = regulator_disable(priv->core_pwr);
  626. - if (ret < 0)
  627. - dev_err(priv->dev,
  628. - "Failed to disable core power: %d\n", ret);
  629. -
  630. - ret = regulator_disable(priv->io_pwr);
  631. - if (ret < 0)
  632. - dev_err(priv->dev, "Failed to disable io pwr: %d\n",
  633. - ret);
  634. -
  635. - mt7530_remove_common(priv);
  636. -
  637. - for (i = 0; i < 2; ++i)
  638. - mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
  639. -}
  640. -
  641. -static void mt7530_shutdown(struct mdio_device *mdiodev)
  642. -{
  643. - struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
  644. -
  645. - if (!priv)
  646. - return;
  647. -
  648. - dsa_switch_shutdown(priv->ds);
  649. -
  650. - dev_set_drvdata(&mdiodev->dev, NULL);
  651. -}
  652. -
  653. -static struct mdio_driver mt7530_mdio_driver = {
  654. - .probe = mt7530_probe,
  655. - .remove = mt7530_remove,
  656. - .shutdown = mt7530_shutdown,
  657. - .mdiodrv.driver = {
  658. - .name = "mt7530",
  659. - .of_match_table = mt7530_of_match,
  660. - },
  661. -};
  662. -
  663. -mdio_module_driver(mt7530_mdio_driver);
  664. +EXPORT_SYMBOL_GPL(mt7530_remove_common);
  665. MODULE_AUTHOR("Sean Wang <[email protected]>");
  666. MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch");
  667. --- a/drivers/net/dsa/mt7530.h
  668. +++ b/drivers/net/dsa/mt7530.h
  669. @@ -834,4 +834,10 @@ static inline void INIT_MT7530_DUMMY_POL
  670. p->reg = reg;
  671. }
  672. +int mt7530_probe_common(struct mt7530_priv *priv);
  673. +void mt7530_remove_common(struct mt7530_priv *priv);
  674. +
  675. +extern const struct dsa_switch_ops mt7530_switch_ops;
  676. +extern const struct mt753x_info mt753x_table[];
  677. +
  678. #endif /* __MT7530_H */