aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/mdio-gpio.c72
-rw-r--r--drivers/net/phy/micrel.c6
-rw-r--r--drivers/net/phy/phy.c27
-rw-r--r--drivers/net/phy/phy_device.c4
4 files changed, 76 insertions, 33 deletions
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index e701433bf52f..5f1a2250018f 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -32,29 +32,39 @@
32 32
33struct mdio_gpio_info { 33struct mdio_gpio_info {
34 struct mdiobb_ctrl ctrl; 34 struct mdiobb_ctrl ctrl;
35 int mdc, mdio; 35 int mdc, mdio, mdo;
36 int mdc_active_low, mdio_active_low, mdo_active_low;
36}; 37};
37 38
38static void *mdio_gpio_of_get_data(struct platform_device *pdev) 39static void *mdio_gpio_of_get_data(struct platform_device *pdev)
39{ 40{
40 struct device_node *np = pdev->dev.of_node; 41 struct device_node *np = pdev->dev.of_node;
41 struct mdio_gpio_platform_data *pdata; 42 struct mdio_gpio_platform_data *pdata;
43 enum of_gpio_flags flags;
42 int ret; 44 int ret;
43 45
44 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 46 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
45 if (!pdata) 47 if (!pdata)
46 return NULL; 48 return NULL;
47 49
48 ret = of_get_gpio(np, 0); 50 ret = of_get_gpio_flags(np, 0, &flags);
49 if (ret < 0) 51 if (ret < 0)
50 return NULL; 52 return NULL;
51 53
52 pdata->mdc = ret; 54 pdata->mdc = ret;
55 pdata->mdc_active_low = flags & OF_GPIO_ACTIVE_LOW;
53 56
54 ret = of_get_gpio(np, 1); 57 ret = of_get_gpio_flags(np, 1, &flags);
55 if (ret < 0) 58 if (ret < 0)
56 return NULL; 59 return NULL;
57 pdata->mdio = ret; 60 pdata->mdio = ret;
61 pdata->mdio_active_low = flags & OF_GPIO_ACTIVE_LOW;
62
63 ret = of_get_gpio_flags(np, 2, &flags);
64 if (ret > 0) {
65 pdata->mdo = ret;
66 pdata->mdo_active_low = flags & OF_GPIO_ACTIVE_LOW;
67 }
58 68
59 return pdata; 69 return pdata;
60} 70}
@@ -64,8 +74,19 @@ static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir)
64 struct mdio_gpio_info *bitbang = 74 struct mdio_gpio_info *bitbang =
65 container_of(ctrl, struct mdio_gpio_info, ctrl); 75 container_of(ctrl, struct mdio_gpio_info, ctrl);
66 76
77 if (bitbang->mdo) {
78 /* Separate output pin. Always set its value to high
79 * when changing direction. If direction is input,
80 * assume the pin serves as pull-up. If direction is
81 * output, the default value is high.
82 */
83 gpio_set_value(bitbang->mdo, 1 ^ bitbang->mdo_active_low);
84 return;
85 }
86
67 if (dir) 87 if (dir)
68 gpio_direction_output(bitbang->mdio, 1); 88 gpio_direction_output(bitbang->mdio,
89 1 ^ bitbang->mdio_active_low);
69 else 90 else
70 gpio_direction_input(bitbang->mdio); 91 gpio_direction_input(bitbang->mdio);
71} 92}
@@ -75,7 +96,7 @@ static int mdio_get(struct mdiobb_ctrl *ctrl)
75 struct mdio_gpio_info *bitbang = 96 struct mdio_gpio_info *bitbang =
76 container_of(ctrl, struct mdio_gpio_info, ctrl); 97 container_of(ctrl, struct mdio_gpio_info, ctrl);
77 98
78 return gpio_get_value(bitbang->mdio); 99 return gpio_get_value(bitbang->mdio) ^ bitbang->mdio_active_low;
79} 100}
80 101
81static void mdio_set(struct mdiobb_ctrl *ctrl, int what) 102static void mdio_set(struct mdiobb_ctrl *ctrl, int what)
@@ -83,7 +104,10 @@ static void mdio_set(struct mdiobb_ctrl *ctrl, int what)
83 struct mdio_gpio_info *bitbang = 104 struct mdio_gpio_info *bitbang =
84 container_of(ctrl, struct mdio_gpio_info, ctrl); 105 container_of(ctrl, struct mdio_gpio_info, ctrl);
85 106
86 gpio_set_value(bitbang->mdio, what); 107 if (bitbang->mdo)
108 gpio_set_value(bitbang->mdo, what ^ bitbang->mdo_active_low);
109 else
110 gpio_set_value(bitbang->mdio, what ^ bitbang->mdio_active_low);
87} 111}
88 112
89static void mdc_set(struct mdiobb_ctrl *ctrl, int what) 113static void mdc_set(struct mdiobb_ctrl *ctrl, int what)
@@ -91,7 +115,7 @@ static void mdc_set(struct mdiobb_ctrl *ctrl, int what)
91 struct mdio_gpio_info *bitbang = 115 struct mdio_gpio_info *bitbang =
92 container_of(ctrl, struct mdio_gpio_info, ctrl); 116 container_of(ctrl, struct mdio_gpio_info, ctrl);
93 117
94 gpio_set_value(bitbang->mdc, what); 118 gpio_set_value(bitbang->mdc, what ^ bitbang->mdc_active_low);
95} 119}
96 120
97static struct mdiobb_ops mdio_gpio_ops = { 121static struct mdiobb_ops mdio_gpio_ops = {
@@ -110,18 +134,22 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev,
110 struct mdio_gpio_info *bitbang; 134 struct mdio_gpio_info *bitbang;
111 int i; 135 int i;
112 136
113 bitbang = kzalloc(sizeof(*bitbang), GFP_KERNEL); 137 bitbang = devm_kzalloc(dev, sizeof(*bitbang), GFP_KERNEL);
114 if (!bitbang) 138 if (!bitbang)
115 goto out; 139 goto out;
116 140
117 bitbang->ctrl.ops = &mdio_gpio_ops; 141 bitbang->ctrl.ops = &mdio_gpio_ops;
118 bitbang->ctrl.reset = pdata->reset; 142 bitbang->ctrl.reset = pdata->reset;
119 bitbang->mdc = pdata->mdc; 143 bitbang->mdc = pdata->mdc;
144 bitbang->mdc_active_low = pdata->mdc_active_low;
120 bitbang->mdio = pdata->mdio; 145 bitbang->mdio = pdata->mdio;
146 bitbang->mdio_active_low = pdata->mdio_active_low;
147 bitbang->mdo = pdata->mdo;
148 bitbang->mdo_active_low = pdata->mdo_active_low;
121 149
122 new_bus = alloc_mdio_bitbang(&bitbang->ctrl); 150 new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
123 if (!new_bus) 151 if (!new_bus)
124 goto out_free_bitbang; 152 goto out;
125 153
126 new_bus->name = "GPIO Bitbanged MDIO", 154 new_bus->name = "GPIO Bitbanged MDIO",
127 155
@@ -138,11 +166,18 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev,
138 166
139 snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id); 167 snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id);
140 168
141 if (gpio_request(bitbang->mdc, "mdc")) 169 if (devm_gpio_request(dev, bitbang->mdc, "mdc"))
170 goto out_free_bus;
171
172 if (devm_gpio_request(dev, bitbang->mdio, "mdio"))
142 goto out_free_bus; 173 goto out_free_bus;
143 174
144 if (gpio_request(bitbang->mdio, "mdio")) 175 if (bitbang->mdo) {
145 goto out_free_mdc; 176 if (devm_gpio_request(dev, bitbang->mdo, "mdo"))
177 goto out_free_bus;
178 gpio_direction_output(bitbang->mdo, 1);
179 gpio_direction_input(bitbang->mdio);
180 }
146 181
147 gpio_direction_output(bitbang->mdc, 0); 182 gpio_direction_output(bitbang->mdc, 0);
148 183
@@ -150,12 +185,8 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev,
150 185
151 return new_bus; 186 return new_bus;
152 187
153out_free_mdc:
154 gpio_free(bitbang->mdc);
155out_free_bus: 188out_free_bus:
156 free_mdio_bitbang(new_bus); 189 free_mdio_bitbang(new_bus);
157out_free_bitbang:
158 kfree(bitbang);
159out: 190out:
160 return NULL; 191 return NULL;
161} 192}
@@ -163,13 +194,8 @@ out:
163static void mdio_gpio_bus_deinit(struct device *dev) 194static void mdio_gpio_bus_deinit(struct device *dev)
164{ 195{
165 struct mii_bus *bus = dev_get_drvdata(dev); 196 struct mii_bus *bus = dev_get_drvdata(dev);
166 struct mdio_gpio_info *bitbang = bus->priv;
167 197
168 dev_set_drvdata(dev, NULL);
169 gpio_free(bitbang->mdio);
170 gpio_free(bitbang->mdc);
171 free_mdio_bitbang(bus); 198 free_mdio_bitbang(bus);
172 kfree(bitbang);
173} 199}
174 200
175static void mdio_gpio_bus_destroy(struct device *dev) 201static void mdio_gpio_bus_destroy(struct device *dev)
@@ -189,6 +215,10 @@ static int mdio_gpio_probe(struct platform_device *pdev)
189 if (pdev->dev.of_node) { 215 if (pdev->dev.of_node) {
190 pdata = mdio_gpio_of_get_data(pdev); 216 pdata = mdio_gpio_of_get_data(pdev);
191 bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio"); 217 bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio");
218 if (bus_id < 0) {
219 dev_warn(&pdev->dev, "failed to get alias id\n");
220 bus_id = 0;
221 }
192 } else { 222 } else {
193 pdata = dev_get_platdata(&pdev->dev); 223 pdata = dev_get_platdata(&pdev->dev);
194 bus_id = pdev->id; 224 bus_id = pdev->id;
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 5ad971a55c5d..d849684231c1 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -246,13 +246,13 @@ static int ksz9021_load_values_from_of(struct phy_device *phydev,
246 if (val1 != -1) 246 if (val1 != -1)
247 newval = ((newval & 0xfff0) | ((val1 / PS_TO_REG) & 0xf) << 0); 247 newval = ((newval & 0xfff0) | ((val1 / PS_TO_REG) & 0xf) << 0);
248 248
249 if (val2 != -1) 249 if (val2 != -2)
250 newval = ((newval & 0xff0f) | ((val2 / PS_TO_REG) & 0xf) << 4); 250 newval = ((newval & 0xff0f) | ((val2 / PS_TO_REG) & 0xf) << 4);
251 251
252 if (val3 != -1) 252 if (val3 != -3)
253 newval = ((newval & 0xf0ff) | ((val3 / PS_TO_REG) & 0xf) << 8); 253 newval = ((newval & 0xf0ff) | ((val3 / PS_TO_REG) & 0xf) << 8);
254 254
255 if (val4 != -1) 255 if (val4 != -4)
256 newval = ((newval & 0x0fff) | ((val4 / PS_TO_REG) & 0xf) << 12); 256 newval = ((newval & 0x0fff) | ((val4 / PS_TO_REG) & 0xf) << 12);
257 257
258 return kszphy_extended_write(phydev, reg, newval); 258 return kszphy_extended_write(phydev, reg, newval);
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 1b6d09aef427..3bc079a67a3d 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -715,7 +715,7 @@ void phy_state_machine(struct work_struct *work)
715 struct delayed_work *dwork = to_delayed_work(work); 715 struct delayed_work *dwork = to_delayed_work(work);
716 struct phy_device *phydev = 716 struct phy_device *phydev =
717 container_of(dwork, struct phy_device, state_queue); 717 container_of(dwork, struct phy_device, state_queue);
718 int needs_aneg = 0, do_suspend = 0; 718 bool needs_aneg = false, do_suspend = false, do_resume = false;
719 int err = 0; 719 int err = 0;
720 720
721 mutex_lock(&phydev->lock); 721 mutex_lock(&phydev->lock);
@@ -727,7 +727,7 @@ void phy_state_machine(struct work_struct *work)
727 case PHY_PENDING: 727 case PHY_PENDING:
728 break; 728 break;
729 case PHY_UP: 729 case PHY_UP:
730 needs_aneg = 1; 730 needs_aneg = true;
731 731
732 phydev->link_timeout = PHY_AN_TIMEOUT; 732 phydev->link_timeout = PHY_AN_TIMEOUT;
733 733
@@ -757,7 +757,7 @@ void phy_state_machine(struct work_struct *work)
757 phydev->adjust_link(phydev->attached_dev); 757 phydev->adjust_link(phydev->attached_dev);
758 758
759 } else if (0 == phydev->link_timeout--) 759 } else if (0 == phydev->link_timeout--)
760 needs_aneg = 1; 760 needs_aneg = true;
761 break; 761 break;
762 case PHY_NOLINK: 762 case PHY_NOLINK:
763 err = phy_read_status(phydev); 763 err = phy_read_status(phydev);
@@ -765,6 +765,17 @@ void phy_state_machine(struct work_struct *work)
765 break; 765 break;
766 766
767 if (phydev->link) { 767 if (phydev->link) {
768 if (AUTONEG_ENABLE == phydev->autoneg) {
769 err = phy_aneg_done(phydev);
770 if (err < 0)
771 break;
772
773 if (!err) {
774 phydev->state = PHY_AN;
775 phydev->link_timeout = PHY_AN_TIMEOUT;
776 break;
777 }
778 }
768 phydev->state = PHY_RUNNING; 779 phydev->state = PHY_RUNNING;
769 netif_carrier_on(phydev->attached_dev); 780 netif_carrier_on(phydev->attached_dev);
770 phydev->adjust_link(phydev->attached_dev); 781 phydev->adjust_link(phydev->attached_dev);
@@ -780,7 +791,7 @@ void phy_state_machine(struct work_struct *work)
780 netif_carrier_on(phydev->attached_dev); 791 netif_carrier_on(phydev->attached_dev);
781 } else { 792 } else {
782 if (0 == phydev->link_timeout--) 793 if (0 == phydev->link_timeout--)
783 needs_aneg = 1; 794 needs_aneg = true;
784 } 795 }
785 796
786 phydev->adjust_link(phydev->attached_dev); 797 phydev->adjust_link(phydev->attached_dev);
@@ -816,7 +827,7 @@ void phy_state_machine(struct work_struct *work)
816 phydev->link = 0; 827 phydev->link = 0;
817 netif_carrier_off(phydev->attached_dev); 828 netif_carrier_off(phydev->attached_dev);
818 phydev->adjust_link(phydev->attached_dev); 829 phydev->adjust_link(phydev->attached_dev);
819 do_suspend = 1; 830 do_suspend = true;
820 } 831 }
821 break; 832 break;
822 case PHY_RESUMING: 833 case PHY_RESUMING:
@@ -865,6 +876,7 @@ void phy_state_machine(struct work_struct *work)
865 } 876 }
866 phydev->adjust_link(phydev->attached_dev); 877 phydev->adjust_link(phydev->attached_dev);
867 } 878 }
879 do_resume = true;
868 break; 880 break;
869 } 881 }
870 882
@@ -872,9 +884,10 @@ void phy_state_machine(struct work_struct *work)
872 884
873 if (needs_aneg) 885 if (needs_aneg)
874 err = phy_start_aneg(phydev); 886 err = phy_start_aneg(phydev);
875 887 else if (do_suspend)
876 if (do_suspend)
877 phy_suspend(phydev); 888 phy_suspend(phydev);
889 else if (do_resume)
890 phy_resume(phydev);
878 891
879 if (err < 0) 892 if (err < 0)
880 phy_error(phydev); 893 phy_error(phydev);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 0ce606624296..4987a1c6dc52 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -614,8 +614,8 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
614 err = phy_init_hw(phydev); 614 err = phy_init_hw(phydev);
615 if (err) 615 if (err)
616 phy_detach(phydev); 616 phy_detach(phydev);
617 617 else
618 phy_resume(phydev); 618 phy_resume(phydev);
619 619
620 return err; 620 return err;
621} 621}