Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: isp1760: otg control register access

The set/clear of the otg control values is done writing to
two different 16bit registers, however we setup the regmap
width for isp1760/61 to 32bit value bits.

So, just access the clear register address (0x376)as the high
part of the otg control register set (0x374), and write the
values in one go to make sure they get clear/set.

Reported-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
Link: https://lore.kernel.org/r/20210827131154.4151862-6-rui.silva@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Rui Miguel Silva and committed by
Greg Kroah-Hartman
9c1587d9 955d0fb5

+42 -24
+26 -24
drivers/usb/isp1760/isp1760-core.c
··· 30 30 { 31 31 struct isp1760_hcd *hcd = &isp->hcd; 32 32 struct isp1760_udc *udc = &isp->udc; 33 + u32 otg_ctrl; 33 34 34 35 /* Low-level chip reset */ 35 36 if (isp->rst_gpio) { ··· 84 83 * 85 84 * TODO: Really support OTG. For now we configure port 1 in device mode 86 85 */ 87 - if (((isp->devflags & ISP1760_FLAG_ISP1761) || 88 - (isp->devflags & ISP1760_FLAG_ISP1763)) && 89 - (isp->devflags & ISP1760_FLAG_PERIPHERAL_EN)) { 90 - isp1760_field_set(hcd->fields, HW_DM_PULLDOWN); 91 - isp1760_field_set(hcd->fields, HW_DP_PULLDOWN); 92 - isp1760_field_set(hcd->fields, HW_OTG_DISABLE); 93 - } else { 94 - isp1760_field_set(hcd->fields, HW_SW_SEL_HC_DC); 95 - isp1760_field_set(hcd->fields, HW_VBUS_DRV); 96 - isp1760_field_set(hcd->fields, HW_SEL_CP_EXT); 86 + if (isp->devflags & ISP1760_FLAG_ISP1761) { 87 + if (isp->devflags & ISP1760_FLAG_PERIPHERAL_EN) { 88 + otg_ctrl = (ISP176x_HW_DM_PULLDOWN_CLEAR | 89 + ISP176x_HW_DP_PULLDOWN_CLEAR | 90 + ISP176x_HW_OTG_DISABLE); 91 + } else { 92 + otg_ctrl = (ISP176x_HW_SW_SEL_HC_DC_CLEAR | 93 + ISP176x_HW_VBUS_DRV | 94 + ISP176x_HW_SEL_CP_EXT); 95 + } 96 + isp1760_reg_write(hcd->regs, ISP176x_HC_OTG_CTRL, otg_ctrl); 97 97 } 98 98 99 99 dev_info(isp->dev, "%s bus width: %u, oc: %s\n", ··· 237 235 [HC_ISO_IRQ_MASK_AND] = REG_FIELD(ISP176x_HC_ISO_IRQ_MASK_AND, 0, 31), 238 236 [HC_INT_IRQ_MASK_AND] = REG_FIELD(ISP176x_HC_INT_IRQ_MASK_AND, 0, 31), 239 237 [HC_ATL_IRQ_MASK_AND] = REG_FIELD(ISP176x_HC_ATL_IRQ_MASK_AND, 0, 31), 240 - [HW_OTG_DISABLE] = REG_FIELD(ISP176x_HC_OTG_CTRL_SET, 10, 10), 241 - [HW_SW_SEL_HC_DC] = REG_FIELD(ISP176x_HC_OTG_CTRL_SET, 7, 7), 242 - [HW_VBUS_DRV] = REG_FIELD(ISP176x_HC_OTG_CTRL_SET, 4, 4), 243 - [HW_SEL_CP_EXT] = REG_FIELD(ISP176x_HC_OTG_CTRL_SET, 3, 3), 244 - [HW_DM_PULLDOWN] = REG_FIELD(ISP176x_HC_OTG_CTRL_SET, 2, 2), 245 - [HW_DP_PULLDOWN] = REG_FIELD(ISP176x_HC_OTG_CTRL_SET, 1, 1), 246 - [HW_DP_PULLUP] = REG_FIELD(ISP176x_HC_OTG_CTRL_SET, 0, 0), 247 - [HW_OTG_DISABLE_CLEAR] = REG_FIELD(ISP176x_HC_OTG_CTRL_CLEAR, 10, 10), 248 - [HW_SW_SEL_HC_DC_CLEAR] = REG_FIELD(ISP176x_HC_OTG_CTRL_CLEAR, 7, 7), 249 - [HW_VBUS_DRV_CLEAR] = REG_FIELD(ISP176x_HC_OTG_CTRL_CLEAR, 4, 4), 250 - [HW_SEL_CP_EXT_CLEAR] = REG_FIELD(ISP176x_HC_OTG_CTRL_CLEAR, 3, 3), 251 - [HW_DM_PULLDOWN_CLEAR] = REG_FIELD(ISP176x_HC_OTG_CTRL_CLEAR, 2, 2), 252 - [HW_DP_PULLDOWN_CLEAR] = REG_FIELD(ISP176x_HC_OTG_CTRL_CLEAR, 1, 1), 253 - [HW_DP_PULLUP_CLEAR] = REG_FIELD(ISP176x_HC_OTG_CTRL_CLEAR, 0, 0), 238 + [HW_OTG_DISABLE_CLEAR] = REG_FIELD(ISP176x_HC_OTG_CTRL, 26, 26), 239 + [HW_SW_SEL_HC_DC_CLEAR] = REG_FIELD(ISP176x_HC_OTG_CTRL, 23, 23), 240 + [HW_VBUS_DRV_CLEAR] = REG_FIELD(ISP176x_HC_OTG_CTRL, 20, 20), 241 + [HW_SEL_CP_EXT_CLEAR] = REG_FIELD(ISP176x_HC_OTG_CTRL, 19, 19), 242 + [HW_DM_PULLDOWN_CLEAR] = REG_FIELD(ISP176x_HC_OTG_CTRL, 18, 18), 243 + [HW_DP_PULLDOWN_CLEAR] = REG_FIELD(ISP176x_HC_OTG_CTRL, 17, 17), 244 + [HW_DP_PULLUP_CLEAR] = REG_FIELD(ISP176x_HC_OTG_CTRL, 16, 16), 245 + [HW_OTG_DISABLE] = REG_FIELD(ISP176x_HC_OTG_CTRL, 10, 10), 246 + [HW_SW_SEL_HC_DC] = REG_FIELD(ISP176x_HC_OTG_CTRL, 7, 7), 247 + [HW_VBUS_DRV] = REG_FIELD(ISP176x_HC_OTG_CTRL, 4, 4), 248 + [HW_SEL_CP_EXT] = REG_FIELD(ISP176x_HC_OTG_CTRL, 3, 3), 249 + [HW_DM_PULLDOWN] = REG_FIELD(ISP176x_HC_OTG_CTRL, 2, 2), 250 + [HW_DP_PULLDOWN] = REG_FIELD(ISP176x_HC_OTG_CTRL, 1, 1), 251 + [HW_DP_PULLUP] = REG_FIELD(ISP176x_HC_OTG_CTRL, 0, 0), 254 252 }; 255 253 256 254 static const struct reg_field isp1763_hc_reg_fields[] = {
+16
drivers/usb/isp1760/isp1760-regs.h
··· 61 61 #define ISP176x_HC_INT_IRQ_MASK_AND 0x328 62 62 #define ISP176x_HC_ATL_IRQ_MASK_AND 0x32c 63 63 64 + #define ISP176x_HC_OTG_CTRL 0x374 64 65 #define ISP176x_HC_OTG_CTRL_SET 0x374 65 66 #define ISP176x_HC_OTG_CTRL_CLEAR 0x376 66 67 ··· 179 178 #define ISP176x_DC_IERESM BIT(4) 180 179 #define ISP176x_DC_IESUSP BIT(3) 181 180 #define ISP176x_DC_IEBRST BIT(0) 181 + 182 + #define ISP176x_HW_OTG_DISABLE_CLEAR BIT(26) 183 + #define ISP176x_HW_SW_SEL_HC_DC_CLEAR BIT(23) 184 + #define ISP176x_HW_VBUS_DRV_CLEAR BIT(20) 185 + #define ISP176x_HW_SEL_CP_EXT_CLEAR BIT(19) 186 + #define ISP176x_HW_DM_PULLDOWN_CLEAR BIT(18) 187 + #define ISP176x_HW_DP_PULLDOWN_CLEAR BIT(17) 188 + #define ISP176x_HW_DP_PULLUP_CLEAR BIT(16) 189 + #define ISP176x_HW_OTG_DISABLE BIT(10) 190 + #define ISP176x_HW_SW_SEL_HC_DC BIT(7) 191 + #define ISP176x_HW_VBUS_DRV BIT(4) 192 + #define ISP176x_HW_SEL_CP_EXT BIT(3) 193 + #define ISP176x_HW_DM_PULLDOWN BIT(2) 194 + #define ISP176x_HW_DP_PULLDOWN BIT(1) 195 + #define ISP176x_HW_DP_PULLUP BIT(0) 182 196 183 197 #define ISP176x_DC_ENDPTYP_ISOC 0x01 184 198 #define ISP176x_DC_ENDPTYP_BULK 0x02