aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2014-11-19 06:59:22 -0500
committerDavid S. Miller <davem@davemloft.net>2014-11-21 14:08:57 -0500
commitc6f9575cc86250422c84972219e2a1bd7ec7e2ae (patch)
treeaf3206c8cafb1fca664b695ccfb375e1846b15bd /drivers/net/phy
parentc3a8e1eddd6c140fbaaf957f7da8f2175f79623d (diff)
net: phy: micrel: refactor interrupt config
Add generic interrupt-config callback and store interrupt-level bitmask in type data for PHY types not using bit 9. Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/micrel.c71
1 files changed, 29 insertions, 42 deletions
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 04fbee846b66..d7eb7b0e6d4e 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -55,8 +55,6 @@
55#define MII_KSZPHY_CTRL MII_KSZPHY_CTRL_2 55#define MII_KSZPHY_CTRL MII_KSZPHY_CTRL_2
56/* bitmap of PHY register to set interrupt mode */ 56/* bitmap of PHY register to set interrupt mode */
57#define KSZPHY_CTRL_INT_ACTIVE_HIGH BIT(9) 57#define KSZPHY_CTRL_INT_ACTIVE_HIGH BIT(9)
58#define KSZ9021_CTRL_INT_ACTIVE_HIGH BIT(14)
59#define KS8737_CTRL_INT_ACTIVE_HIGH BIT(14)
60#define KSZPHY_RMII_REF_CLK_SEL BIT(7) 58#define KSZPHY_RMII_REF_CLK_SEL BIT(7)
61 59
62/* Write/read to/from extended registers */ 60/* Write/read to/from extended registers */
@@ -75,6 +73,7 @@
75 73
76struct kszphy_type { 74struct kszphy_type {
77 u32 led_mode_reg; 75 u32 led_mode_reg;
76 u16 interrupt_level_mask;
78 bool has_broadcast_disable; 77 bool has_broadcast_disable;
79 bool has_rmii_ref_clk_sel; 78 bool has_rmii_ref_clk_sel;
80}; 79};
@@ -105,6 +104,14 @@ static const struct kszphy_type ksz8081_type = {
105 .has_rmii_ref_clk_sel = true, 104 .has_rmii_ref_clk_sel = true,
106}; 105};
107 106
107static const struct kszphy_type ks8737_type = {
108 .interrupt_level_mask = BIT(14),
109};
110
111static const struct kszphy_type ksz9021_type = {
112 .interrupt_level_mask = BIT(14),
113};
114
108static int kszphy_extended_write(struct phy_device *phydev, 115static int kszphy_extended_write(struct phy_device *phydev,
109 u32 regnum, u16 val) 116 u32 regnum, u16 val)
110{ 117{
@@ -129,54 +136,31 @@ static int kszphy_ack_interrupt(struct phy_device *phydev)
129 return (rc < 0) ? rc : 0; 136 return (rc < 0) ? rc : 0;
130} 137}
131 138
132static int kszphy_set_interrupt(struct phy_device *phydev)
133{
134 int temp;
135 temp = (PHY_INTERRUPT_ENABLED == phydev->interrupts) ?
136 KSZPHY_INTCS_ALL : 0;
137 return phy_write(phydev, MII_KSZPHY_INTCS, temp);
138}
139
140static int kszphy_config_intr(struct phy_device *phydev) 139static int kszphy_config_intr(struct phy_device *phydev)
141{ 140{
142 int temp, rc; 141 const struct kszphy_type *type = phydev->drv->driver_data;
143 142 int temp;
144 /* set the interrupt pin active low */ 143 u16 mask;
145 temp = phy_read(phydev, MII_KSZPHY_CTRL);
146 if (temp < 0)
147 return temp;
148 temp &= ~KSZPHY_CTRL_INT_ACTIVE_HIGH;
149 phy_write(phydev, MII_KSZPHY_CTRL, temp);
150 rc = kszphy_set_interrupt(phydev);
151 return rc < 0 ? rc : 0;
152}
153 144
154static int ksz9021_config_intr(struct phy_device *phydev) 145 if (type && type->interrupt_level_mask)
155{ 146 mask = type->interrupt_level_mask;
156 int temp, rc; 147 else
148 mask = KSZPHY_CTRL_INT_ACTIVE_HIGH;
157 149
158 /* set the interrupt pin active low */ 150 /* set the interrupt pin active low */
159 temp = phy_read(phydev, MII_KSZPHY_CTRL); 151 temp = phy_read(phydev, MII_KSZPHY_CTRL);
160 if (temp < 0) 152 if (temp < 0)
161 return temp; 153 return temp;
162 temp &= ~KSZ9021_CTRL_INT_ACTIVE_HIGH; 154 temp &= ~mask;
163 phy_write(phydev, MII_KSZPHY_CTRL, temp); 155 phy_write(phydev, MII_KSZPHY_CTRL, temp);
164 rc = kszphy_set_interrupt(phydev);
165 return rc < 0 ? rc : 0;
166}
167 156
168static int ks8737_config_intr(struct phy_device *phydev) 157 /* enable / disable interrupts */
169{ 158 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
170 int temp, rc; 159 temp = KSZPHY_INTCS_ALL;
160 else
161 temp = 0;
171 162
172 /* set the interrupt pin active low */ 163 return phy_write(phydev, MII_KSZPHY_INTCS, temp);
173 temp = phy_read(phydev, MII_KSZPHY_CTRL);
174 if (temp < 0)
175 return temp;
176 temp &= ~KS8737_CTRL_INT_ACTIVE_HIGH;
177 phy_write(phydev, MII_KSZPHY_CTRL, temp);
178 rc = kszphy_set_interrupt(phydev);
179 return rc < 0 ? rc : 0;
180} 164}
181 165
182static int kszphy_rmii_clk_sel(struct phy_device *phydev, bool val) 166static int kszphy_rmii_clk_sel(struct phy_device *phydev, bool val)
@@ -581,11 +565,12 @@ static struct phy_driver ksphy_driver[] = {
581 .name = "Micrel KS8737", 565 .name = "Micrel KS8737",
582 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), 566 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
583 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, 567 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
568 .driver_data = &ks8737_type,
584 .config_init = kszphy_config_init, 569 .config_init = kszphy_config_init,
585 .config_aneg = genphy_config_aneg, 570 .config_aneg = genphy_config_aneg,
586 .read_status = genphy_read_status, 571 .read_status = genphy_read_status,
587 .ack_interrupt = kszphy_ack_interrupt, 572 .ack_interrupt = kszphy_ack_interrupt,
588 .config_intr = ks8737_config_intr, 573 .config_intr = kszphy_config_intr,
589 .suspend = genphy_suspend, 574 .suspend = genphy_suspend,
590 .resume = genphy_resume, 575 .resume = genphy_resume,
591 .driver = { .owner = THIS_MODULE,}, 576 .driver = { .owner = THIS_MODULE,},
@@ -726,11 +711,12 @@ static struct phy_driver ksphy_driver[] = {
726 .name = "Micrel KSZ9021 Gigabit PHY", 711 .name = "Micrel KSZ9021 Gigabit PHY",
727 .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause), 712 .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause),
728 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, 713 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
714 .driver_data = &ksz9021_type,
729 .config_init = ksz9021_config_init, 715 .config_init = ksz9021_config_init,
730 .config_aneg = genphy_config_aneg, 716 .config_aneg = genphy_config_aneg,
731 .read_status = genphy_read_status, 717 .read_status = genphy_read_status,
732 .ack_interrupt = kszphy_ack_interrupt, 718 .ack_interrupt = kszphy_ack_interrupt,
733 .config_intr = ksz9021_config_intr, 719 .config_intr = kszphy_config_intr,
734 .suspend = genphy_suspend, 720 .suspend = genphy_suspend,
735 .resume = genphy_resume, 721 .resume = genphy_resume,
736 .read_mmd_indirect = ksz9021_rd_mmd_phyreg, 722 .read_mmd_indirect = ksz9021_rd_mmd_phyreg,
@@ -742,11 +728,12 @@ static struct phy_driver ksphy_driver[] = {
742 .name = "Micrel KSZ9031 Gigabit PHY", 728 .name = "Micrel KSZ9031 Gigabit PHY",
743 .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause), 729 .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause),
744 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, 730 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
731 .driver_data = &ksz9021_type,
745 .config_init = ksz9031_config_init, 732 .config_init = ksz9031_config_init,
746 .config_aneg = genphy_config_aneg, 733 .config_aneg = genphy_config_aneg,
747 .read_status = genphy_read_status, 734 .read_status = genphy_read_status,
748 .ack_interrupt = kszphy_ack_interrupt, 735 .ack_interrupt = kszphy_ack_interrupt,
749 .config_intr = ksz9021_config_intr, 736 .config_intr = kszphy_config_intr,
750 .suspend = genphy_suspend, 737 .suspend = genphy_suspend,
751 .resume = genphy_resume, 738 .resume = genphy_resume,
752 .driver = { .owner = THIS_MODULE, }, 739 .driver = { .owner = THIS_MODULE, },