|
40 | 40 | #include <linux/power_supply.h>
|
41 | 41 | #include <linux/regulator/consumer.h>
|
42 | 42 | #include <linux/reset.h>
|
| 43 | +#include <linux/spinlock.h> |
43 | 44 | #include <linux/usb/of.h>
|
44 | 45 | #include <linux/workqueue.h>
|
45 | 46 |
|
@@ -112,7 +113,7 @@ struct sun4i_usb_phy_data {
|
112 | 113 | void __iomem *base;
|
113 | 114 | const struct sun4i_usb_phy_cfg *cfg;
|
114 | 115 | enum usb_dr_mode dr_mode;
|
115 |
| - struct mutex mutex; |
| 116 | + spinlock_t reg_lock; /* guard access to phyctl reg */ |
116 | 117 | struct sun4i_usb_phy {
|
117 | 118 | struct phy *phy;
|
118 | 119 | void __iomem *pmu;
|
@@ -179,9 +180,10 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
|
179 | 180 | struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
|
180 | 181 | u32 temp, usbc_bit = BIT(phy->index * 2);
|
181 | 182 | void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset;
|
| 183 | + unsigned long flags; |
182 | 184 | int i;
|
183 | 185 |
|
184 |
| - mutex_lock(&phy_data->mutex); |
| 186 | + spin_lock_irqsave(&phy_data->reg_lock, flags); |
185 | 187 |
|
186 | 188 | if (phy_data->cfg->type == sun8i_a33_phy) {
|
187 | 189 | /* A33 needs us to set phyctl to 0 explicitly */
|
@@ -218,7 +220,8 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
|
218 | 220 |
|
219 | 221 | data >>= 1;
|
220 | 222 | }
|
221 |
| - mutex_unlock(&phy_data->mutex); |
| 223 | + |
| 224 | + spin_unlock_irqrestore(&phy_data->reg_lock, flags); |
222 | 225 | }
|
223 | 226 |
|
224 | 227 | static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable)
|
@@ -577,7 +580,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
|
577 | 580 | if (!data)
|
578 | 581 | return -ENOMEM;
|
579 | 582 |
|
580 |
| - mutex_init(&data->mutex); |
| 583 | + spin_lock_init(&data->reg_lock); |
581 | 584 | INIT_DELAYED_WORK(&data->detect, sun4i_usb_phy0_id_vbus_det_scan);
|
582 | 585 | dev_set_drvdata(dev, data);
|
583 | 586 | data->cfg = of_device_get_match_data(dev);
|
|
0 commit comments