* [PATCH 1/5] usb: gadget: udc: lpc32xx: simplify probe
2019-04-09 12:09 [PATCH 0/5] usb: gadget: udc: lpc32xx: add stotg04 phy support Alexandre Belloni
@ 2019-04-09 12:09 ` Alexandre Belloni
2019-04-09 12:09 ` [PATCH 2/5] usb: gadget: udc: lpc32xx: simplify vbus handling Alexandre Belloni
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Alexandre Belloni @ 2019-04-09 12:09 UTC (permalink / raw)
To: Felipe Balbi, Vladimir Zapolskiy
Cc: Greg Kroah-Hartman, Sylvain Lemieux, linux-usb, linux-arm-kernel,
linux-kernel, Alexandre Belloni
Simplify .probe and .remove by using devm managed allocations and requests.
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
drivers/usb/gadget/udc/lpc32xx_udc.c | 93 ++++++++--------------------
1 file changed, 25 insertions(+), 68 deletions(-)
diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c
index b0781771704e..5546cb509085 100644
--- a/drivers/usb/gadget/udc/lpc32xx_udc.c
+++ b/drivers/usb/gadget/udc/lpc32xx_udc.c
@@ -129,8 +129,6 @@ struct lpc32xx_udc {
/* Board and device specific */
struct lpc32xx_usbd_cfg *board;
- u32 io_p_start;
- u32 io_p_size;
void __iomem *udp_baseaddr;
int udp_irq[4];
struct clk *usb_slv_clk;
@@ -2999,7 +2997,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
dma_addr_t dma_handle;
struct device_node *isp1301_node;
- udc = kmemdup(&controller_template, sizeof(*udc), GFP_KERNEL);
+ udc = devm_kmemdup(dev, &controller_template, sizeof(*udc), GFP_KERNEL);
if (!udc)
return -ENOMEM;
@@ -3022,8 +3020,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
udc->isp1301_i2c_client = isp1301_get_client(isp1301_node);
if (!udc->isp1301_i2c_client) {
- retval = -EPROBE_DEFER;
- goto phy_fail;
+ return -EPROBE_DEFER;
}
dev_info(udc->dev, "ISP1301 I2C device at address 0x%x\n",
@@ -3032,7 +3029,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
pdev->dev.dma_mask = &lpc32xx_usbd_dmamask;
retval = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (retval)
- goto resource_fail;
+ return retval;
udc->board = &lpc32xx_usbddata;
@@ -3045,10 +3042,8 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
* IORESOURCE_IRQ, USB transceiver interrupt number
*/
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- retval = -ENXIO;
- goto resource_fail;
- }
+ if (!res)
+ return -ENXIO;
spin_lock_init(&udc->lock);
@@ -3058,39 +3053,28 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
if (udc->udp_irq[i] < 0) {
dev_err(udc->dev,
"irq resource %d not available!\n", i);
- retval = udc->udp_irq[i];
- goto irq_fail;
+ return udc->udp_irq[i];
}
}
- udc->io_p_start = res->start;
- udc->io_p_size = resource_size(res);
- if (!request_mem_region(udc->io_p_start, udc->io_p_size, driver_name)) {
- dev_err(udc->dev, "someone's using UDC memory\n");
- retval = -EBUSY;
- goto request_mem_region_fail;
- }
-
- udc->udp_baseaddr = ioremap(udc->io_p_start, udc->io_p_size);
+ udc->udp_baseaddr = devm_ioremap_resource(dev, res);
if (!udc->udp_baseaddr) {
- retval = -ENOMEM;
dev_err(udc->dev, "IO map failure\n");
- goto io_map_fail;
+ return -ENOMEM;
}
/* Get USB device clock */
- udc->usb_slv_clk = clk_get(&pdev->dev, NULL);
+ udc->usb_slv_clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(udc->usb_slv_clk)) {
dev_err(udc->dev, "failed to acquire USB device clock\n");
- retval = PTR_ERR(udc->usb_slv_clk);
- goto usb_clk_get_fail;
+ return PTR_ERR(udc->usb_slv_clk);
}
/* Enable USB device clock */
retval = clk_prepare_enable(udc->usb_slv_clk);
if (retval < 0) {
dev_err(udc->dev, "failed to start USB device clock\n");
- goto usb_clk_enable_fail;
+ return retval;
}
/* Setup deferred workqueue data */
@@ -3134,37 +3118,37 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
/* Request IRQs - low and high priority USB device IRQs are routed to
* the same handler, while the DMA interrupt is routed elsewhere */
- retval = request_irq(udc->udp_irq[IRQ_USB_LP], lpc32xx_usb_lp_irq,
- 0, "udc_lp", udc);
+ retval = devm_request_irq(dev, udc->udp_irq[IRQ_USB_LP],
+ lpc32xx_usb_lp_irq, 0, "udc_lp", udc);
if (retval < 0) {
dev_err(udc->dev, "LP request irq %d failed\n",
udc->udp_irq[IRQ_USB_LP]);
- goto irq_lp_fail;
+ goto irq_req_fail;
}
- retval = request_irq(udc->udp_irq[IRQ_USB_HP], lpc32xx_usb_hp_irq,
- 0, "udc_hp", udc);
+ retval = devm_request_irq(dev, udc->udp_irq[IRQ_USB_HP],
+ lpc32xx_usb_hp_irq, 0, "udc_hp", udc);
if (retval < 0) {
dev_err(udc->dev, "HP request irq %d failed\n",
udc->udp_irq[IRQ_USB_HP]);
- goto irq_hp_fail;
+ goto irq_req_fail;
}
- retval = request_irq(udc->udp_irq[IRQ_USB_DEVDMA],
- lpc32xx_usb_devdma_irq, 0, "udc_dma", udc);
+ retval = devm_request_irq(dev, udc->udp_irq[IRQ_USB_DEVDMA],
+ lpc32xx_usb_devdma_irq, 0, "udc_dma", udc);
if (retval < 0) {
dev_err(udc->dev, "DEV request irq %d failed\n",
udc->udp_irq[IRQ_USB_DEVDMA]);
- goto irq_dev_fail;
+ goto irq_req_fail;
}
/* The transceiver interrupt is used for VBUS detection and will
kick off the VBUS handler function */
- retval = request_irq(udc->udp_irq[IRQ_USB_ATX], lpc32xx_usb_vbus_irq,
- 0, "udc_otg", udc);
+ retval = devm_request_irq(dev, udc->udp_irq[IRQ_USB_ATX],
+ lpc32xx_usb_vbus_irq, 0, "udc_otg", udc);
if (retval < 0) {
dev_err(udc->dev, "VBUS request irq %d failed\n",
udc->udp_irq[IRQ_USB_ATX]);
- goto irq_xcvr_fail;
+ goto irq_req_fail;
}
/* Initialize wait queue */
@@ -3190,32 +3174,15 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
return 0;
add_gadget_fail:
- free_irq(udc->udp_irq[IRQ_USB_ATX], udc);
-irq_xcvr_fail:
- free_irq(udc->udp_irq[IRQ_USB_DEVDMA], udc);
-irq_dev_fail:
- free_irq(udc->udp_irq[IRQ_USB_HP], udc);
-irq_hp_fail:
- free_irq(udc->udp_irq[IRQ_USB_LP], udc);
-irq_lp_fail:
+irq_req_fail:
dma_pool_destroy(udc->dd_cache);
dma_alloc_fail:
dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE,
udc->udca_v_base, udc->udca_p_base);
i2c_fail:
clk_disable_unprepare(udc->usb_slv_clk);
-usb_clk_enable_fail:
- clk_put(udc->usb_slv_clk);
-usb_clk_get_fail:
- iounmap(udc->udp_baseaddr);
-io_map_fail:
- release_mem_region(udc->io_p_start, udc->io_p_size);
dev_err(udc->dev, "%s probe failed, %d\n", driver_name, retval);
-request_mem_region_fail:
-irq_fail:
-resource_fail:
-phy_fail:
- kfree(udc);
+
return retval;
}
@@ -3231,24 +3198,14 @@ static int lpc32xx_udc_remove(struct platform_device *pdev)
udc_disable(udc);
pullup(udc, 0);
- free_irq(udc->udp_irq[IRQ_USB_ATX], udc);
-
device_init_wakeup(&pdev->dev, 0);
remove_debug_file(udc);
dma_pool_destroy(udc->dd_cache);
dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE,
udc->udca_v_base, udc->udca_p_base);
- free_irq(udc->udp_irq[IRQ_USB_DEVDMA], udc);
- free_irq(udc->udp_irq[IRQ_USB_HP], udc);
- free_irq(udc->udp_irq[IRQ_USB_LP], udc);
clk_disable_unprepare(udc->usb_slv_clk);
- clk_put(udc->usb_slv_clk);
-
- iounmap(udc->udp_baseaddr);
- release_mem_region(udc->io_p_start, udc->io_p_size);
- kfree(udc);
return 0;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/5] usb: gadget: udc: lpc32xx: simplify vbus handling
2019-04-09 12:09 [PATCH 0/5] usb: gadget: udc: lpc32xx: add stotg04 phy support Alexandre Belloni
2019-04-09 12:09 ` [PATCH 1/5] usb: gadget: udc: lpc32xx: simplify probe Alexandre Belloni
@ 2019-04-09 12:09 ` Alexandre Belloni
2019-04-09 12:09 ` [PATCH 3/5] usb: gadget: udc: lpc32xx: properly setup phy interrupts Alexandre Belloni
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Alexandre Belloni @ 2019-04-09 12:09 UTC (permalink / raw)
To: Felipe Balbi, Vladimir Zapolskiy
Cc: Greg Kroah-Hartman, Sylvain Lemieux, linux-usb, linux-arm-kernel,
linux-kernel, Alexandre Belloni
Use a threaded IRQ to handle vbus_work instead of using the global
worqueue.
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
drivers/usb/gadget/udc/lpc32xx_udc.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c
index 5546cb509085..777279fa4637 100644
--- a/drivers/usb/gadget/udc/lpc32xx_udc.c
+++ b/drivers/usb/gadget/udc/lpc32xx_udc.c
@@ -152,7 +152,6 @@ struct lpc32xx_udc {
/* Work queues related to I2C support */
struct work_struct pullup_job;
- struct work_struct vbus_job;
struct work_struct power_job;
/* USB device peripheral - various */
@@ -2828,11 +2827,9 @@ static irqreturn_t lpc32xx_usb_devdma_irq(int irq, void *_udc)
* VBUS detection, pullup handler, and Gadget cable state notification
*
*/
-static void vbus_work(struct work_struct *work)
+static void vbus_work(struct lpc32xx_udc *udc)
{
u8 value;
- struct lpc32xx_udc *udc = container_of(work, struct lpc32xx_udc,
- vbus_job);
if (udc->enabled != 0) {
/* Discharge VBUS real quick */
@@ -2877,9 +2874,7 @@ static irqreturn_t lpc32xx_usb_vbus_irq(int irq, void *_udc)
{
struct lpc32xx_udc *udc = _udc;
- /* Defer handling of VBUS IRQ to work queue */
- disable_irq_nosync(udc->udp_irq[IRQ_USB_ATX]);
- schedule_work(&udc->vbus_job);
+ vbus_work(udc);
return IRQ_HANDLED;
}
@@ -2908,7 +2903,7 @@ static int lpc32xx_start(struct usb_gadget *gadget,
/* Force VBUS process once to check for cable insertion */
udc->last_vbus = udc->vbus = 0;
- schedule_work(&udc->vbus_job);
+ vbus_work(udc);
/* Do not re-enable ATX IRQ (3) */
for (i = IRQ_USB_LP; i < IRQ_USB_ATX; i++)
@@ -3080,7 +3075,6 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
/* Setup deferred workqueue data */
udc->poweron = udc->pullup = 0;
INIT_WORK(&udc->pullup_job, pullup_work);
- INIT_WORK(&udc->vbus_job, vbus_work);
#ifdef CONFIG_PM
INIT_WORK(&udc->power_job, power_work);
#endif
@@ -3143,8 +3137,9 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
/* The transceiver interrupt is used for VBUS detection and will
kick off the VBUS handler function */
- retval = devm_request_irq(dev, udc->udp_irq[IRQ_USB_ATX],
- lpc32xx_usb_vbus_irq, 0, "udc_otg", udc);
+ retval = devm_request_threaded_irq(dev, udc->udp_irq[IRQ_USB_ATX], NULL,
+ lpc32xx_usb_vbus_irq, IRQF_ONESHOT,
+ "udc_otg", udc);
if (retval < 0) {
dev_err(udc->dev, "VBUS request irq %d failed\n",
udc->udp_irq[IRQ_USB_ATX]);
--
2.20.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/5] usb: gadget: udc: lpc32xx: properly setup phy interrupts
2019-04-09 12:09 [PATCH 0/5] usb: gadget: udc: lpc32xx: add stotg04 phy support Alexandre Belloni
2019-04-09 12:09 ` [PATCH 1/5] usb: gadget: udc: lpc32xx: simplify probe Alexandre Belloni
2019-04-09 12:09 ` [PATCH 2/5] usb: gadget: udc: lpc32xx: simplify vbus handling Alexandre Belloni
@ 2019-04-09 12:09 ` Alexandre Belloni
2019-04-09 12:09 ` [PATCH 4/5] usb: gadget: udc: lpc32xx: add support for stotg04 phy Alexandre Belloni
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Alexandre Belloni @ 2019-04-09 12:09 UTC (permalink / raw)
To: Felipe Balbi, Vladimir Zapolskiy
Cc: Greg Kroah-Hartman, Sylvain Lemieux, linux-usb, linux-arm-kernel,
linux-kernel, Alexandre Belloni
Only INT_VBUS_VLD is set to generate ATX interrupts on the phy but
INT_SESS_VLD is checked in vbus_work. This leads to cases where
hot-plugging USB doesn't work after boot.
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
drivers/usb/gadget/udc/lpc32xx_udc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c
index 777279fa4637..12f2d76e50fe 100644
--- a/drivers/usb/gadget/udc/lpc32xx_udc.c
+++ b/drivers/usb/gadget/udc/lpc32xx_udc.c
@@ -604,11 +604,11 @@ static void isp1301_udc_configure(struct lpc32xx_udc *udc)
i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR, ~0);
i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
- ISP1301_I2C_INTERRUPT_FALLING, INT_VBUS_VLD);
+ ISP1301_I2C_INTERRUPT_FALLING, INT_SESS_VLD | INT_VBUS_VLD);
i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR, ~0);
i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
- ISP1301_I2C_INTERRUPT_RISING, INT_VBUS_VLD);
+ ISP1301_I2C_INTERRUPT_RISING, INT_SESS_VLD | INT_VBUS_VLD);
dev_info(udc->dev, "ISP1301 Vendor ID : 0x%04x\n",
i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x00));
--
2.20.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/5] usb: gadget: udc: lpc32xx: add support for stotg04 phy
2019-04-09 12:09 [PATCH 0/5] usb: gadget: udc: lpc32xx: add stotg04 phy support Alexandre Belloni
` (2 preceding siblings ...)
2019-04-09 12:09 ` [PATCH 3/5] usb: gadget: udc: lpc32xx: properly setup phy interrupts Alexandre Belloni
@ 2019-04-09 12:09 ` Alexandre Belloni
2019-04-09 12:09 ` [PATCH 5/5] usb: gadget: udc: lpc32xx: rework interrupt handling Alexandre Belloni
2019-05-13 11:32 ` [PATCH 0/5] usb: gadget: udc: lpc32xx: add stotg04 phy support James Grant
5 siblings, 0 replies; 8+ messages in thread
From: Alexandre Belloni @ 2019-04-09 12:09 UTC (permalink / raw)
To: Felipe Balbi, Vladimir Zapolskiy
Cc: Greg Kroah-Hartman, Sylvain Lemieux, linux-usb, linux-arm-kernel,
linux-kernel, Alexandre Belloni
The STOTG04 phy is used as a drop-in replacement of the ISP1301 but some
bits doesn't have exactly the same meaning and this can lead to issues.
Detect the phy dynamically and avoid writing to reserved bits.
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
drivers/usb/gadget/udc/lpc32xx_udc.c | 32 +++++++++++++++++++++++-----
1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c
index 12f2d76e50fe..5d6246d23b99 100644
--- a/drivers/usb/gadget/udc/lpc32xx_udc.c
+++ b/drivers/usb/gadget/udc/lpc32xx_udc.c
@@ -115,6 +115,11 @@ struct lpc32xx_ep {
bool wedge;
};
+enum atx_type {
+ ISP1301,
+ STOTG04,
+};
+
/*
* Common UDC structure
*/
@@ -149,6 +154,7 @@ struct lpc32xx_udc {
u8 last_vbus;
int pullup;
int poweron;
+ enum atx_type atx;
/* Work queues related to I2C support */
struct work_struct pullup_job;
@@ -550,6 +556,15 @@ static inline void remove_debug_file(struct lpc32xx_udc *udc) {}
/* Primary initialization sequence for the ISP1301 transceiver */
static void isp1301_udc_configure(struct lpc32xx_udc *udc)
{
+ u8 value;
+ s32 vendor, product;
+
+ vendor = i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x00);
+ product = i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x02);
+
+ if (vendor == 0x0483 && product == 0xa0c4)
+ udc->atx = STOTG04;
+
/* LPC32XX only supports DAT_SE0 USB mode */
/* This sequence is important */
@@ -569,8 +584,12 @@ static void isp1301_udc_configure(struct lpc32xx_udc *udc)
*/
i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
(ISP1301_I2C_MODE_CONTROL_2 | ISP1301_I2C_REG_CLEAR_ADDR), ~0);
+
+ value = MC2_BI_DI;
+ if (udc->atx != STOTG04)
+ value |= MC2_SPD_SUSP_CTRL;
i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
- ISP1301_I2C_MODE_CONTROL_2, (MC2_BI_DI | MC2_SPD_SUSP_CTRL));
+ ISP1301_I2C_MODE_CONTROL_2, value);
/* Driver VBUS_DRV high or low depending on board setup */
if (udc->board->vbus_drv_pol != 0)
@@ -610,12 +629,11 @@ static void isp1301_udc_configure(struct lpc32xx_udc *udc)
i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
ISP1301_I2C_INTERRUPT_RISING, INT_SESS_VLD | INT_VBUS_VLD);
- dev_info(udc->dev, "ISP1301 Vendor ID : 0x%04x\n",
- i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x00));
- dev_info(udc->dev, "ISP1301 Product ID : 0x%04x\n",
- i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x02));
+ dev_info(udc->dev, "ISP1301 Vendor ID : 0x%04x\n", vendor);
+ dev_info(udc->dev, "ISP1301 Product ID : 0x%04x\n", product);
dev_info(udc->dev, "ISP1301 Version ID : 0x%04x\n",
i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x14));
+
}
/* Enables or disables the USB device pullup via the ISP1301 transceiver */
@@ -658,6 +676,10 @@ static void isp1301_pullup_enable(struct lpc32xx_udc *udc, int en_pullup,
/* Powers up or down the ISP1301 transceiver */
static void isp1301_set_powerstate(struct lpc32xx_udc *udc, int enable)
{
+ /* There is no "global power down" register for stotg04 */
+ if (udc->atx == STOTG04)
+ return;
+
if (enable != 0)
/* Power up ISP1301 - this ISP1301 will automatically wakeup
when VBUS is detected */
--
2.20.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/5] usb: gadget: udc: lpc32xx: rework interrupt handling
2019-04-09 12:09 [PATCH 0/5] usb: gadget: udc: lpc32xx: add stotg04 phy support Alexandre Belloni
` (3 preceding siblings ...)
2019-04-09 12:09 ` [PATCH 4/5] usb: gadget: udc: lpc32xx: add support for stotg04 phy Alexandre Belloni
@ 2019-04-09 12:09 ` Alexandre Belloni
2019-05-13 11:32 ` [PATCH 0/5] usb: gadget: udc: lpc32xx: add stotg04 phy support James Grant
5 siblings, 0 replies; 8+ messages in thread
From: Alexandre Belloni @ 2019-04-09 12:09 UTC (permalink / raw)
To: Felipe Balbi, Vladimir Zapolskiy
Cc: Greg Kroah-Hartman, Sylvain Lemieux, linux-usb, linux-arm-kernel,
linux-kernel, Alexandre Belloni
There is no actual need to do the enable/disable_irq dance. Instead enable
the interrupts on the phy only when necessary.
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
drivers/usb/gadget/udc/lpc32xx_udc.c | 29 ++++++++++------------------
1 file changed, 10 insertions(+), 19 deletions(-)
diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c
index 5d6246d23b99..d8f1c60793ed 100644
--- a/drivers/usb/gadget/udc/lpc32xx_udc.c
+++ b/drivers/usb/gadget/udc/lpc32xx_udc.c
@@ -617,17 +617,13 @@ static void isp1301_udc_configure(struct lpc32xx_udc *udc)
(ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR),
OTG1_VBUS_DISCHRG);
- /* Clear and enable VBUS high edge interrupt */
i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
ISP1301_I2C_INTERRUPT_LATCH | ISP1301_I2C_REG_CLEAR_ADDR, ~0);
+
i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR, ~0);
- i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
- ISP1301_I2C_INTERRUPT_FALLING, INT_SESS_VLD | INT_VBUS_VLD);
i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR, ~0);
- i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
- ISP1301_I2C_INTERRUPT_RISING, INT_SESS_VLD | INT_VBUS_VLD);
dev_info(udc->dev, "ISP1301 Vendor ID : 0x%04x\n", vendor);
dev_info(udc->dev, "ISP1301 Product ID : 0x%04x\n", product);
@@ -2887,9 +2883,6 @@ static void vbus_work(struct lpc32xx_udc *udc)
lpc32xx_vbus_session(&udc->gadget, udc->vbus);
}
}
-
- /* Re-enable after completion */
- enable_irq(udc->udp_irq[IRQ_USB_ATX]);
}
static irqreturn_t lpc32xx_usb_vbus_irq(int irq, void *_udc)
@@ -2905,7 +2898,6 @@ static int lpc32xx_start(struct usb_gadget *gadget,
struct usb_gadget_driver *driver)
{
struct lpc32xx_udc *udc = to_udc(gadget);
- int i;
if (!driver || driver->max_speed < USB_SPEED_FULL || !driver->setup) {
dev_err(udc->dev, "bad parameter.\n");
@@ -2927,20 +2919,23 @@ static int lpc32xx_start(struct usb_gadget *gadget,
udc->last_vbus = udc->vbus = 0;
vbus_work(udc);
- /* Do not re-enable ATX IRQ (3) */
- for (i = IRQ_USB_LP; i < IRQ_USB_ATX; i++)
- enable_irq(udc->udp_irq[i]);
+ /* enable interrupts */
+ i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+ ISP1301_I2C_INTERRUPT_FALLING, INT_SESS_VLD | INT_VBUS_VLD);
+ i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+ ISP1301_I2C_INTERRUPT_RISING, INT_SESS_VLD | INT_VBUS_VLD);
return 0;
}
static int lpc32xx_stop(struct usb_gadget *gadget)
{
- int i;
struct lpc32xx_udc *udc = to_udc(gadget);
- for (i = IRQ_USB_LP; i <= IRQ_USB_ATX; i++)
- disable_irq(udc->udp_irq[i]);
+ i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+ ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR, ~0);
+ i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+ ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR, ~0);
if (udc->clocked) {
spin_lock(&udc->lock);
@@ -3172,10 +3167,6 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
init_waitqueue_head(&udc->ep_disable_wait_queue);
atomic_set(&udc->enabled_ep_cnt, 0);
- /* Keep all IRQs disabled until GadgetFS starts up */
- for (i = IRQ_USB_LP; i <= IRQ_USB_ATX; i++)
- disable_irq(udc->udp_irq[i]);
-
retval = usb_add_gadget_udc(dev, &udc->gadget);
if (retval < 0)
goto add_gadget_fail;
--
2.20.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 0/5] usb: gadget: udc: lpc32xx: add stotg04 phy support
2019-04-09 12:09 [PATCH 0/5] usb: gadget: udc: lpc32xx: add stotg04 phy support Alexandre Belloni
` (4 preceding siblings ...)
2019-04-09 12:09 ` [PATCH 5/5] usb: gadget: udc: lpc32xx: rework interrupt handling Alexandre Belloni
@ 2019-05-13 11:32 ` James Grant
2019-05-22 15:00 ` Sylvain Lemieux
5 siblings, 1 reply; 8+ messages in thread
From: James Grant @ 2019-05-13 11:32 UTC (permalink / raw)
To: Alexandre Belloni, Felipe Balbi, Vladimir Zapolskiy
Cc: Greg Kroah-Hartman, Sylvain Lemieux, linux-usb, linux-arm-kernel,
linux-kernel, Alexandre Belloni
Tested with a board containing LPC3250 SOC and STOTG04 PHY by using
serial gadget.
Needed patch "[PATCH] usb: gadget: udc: lpc32xx: allocate descriptor
with GFP_ATOMIC" also.
Tested-by: James Grant <jamesg@zaltys.org>
Regards,
James Grant.
On 09/04/2019 14:09, Alexandre Belloni Wrote:
> Hi,
>
> This series starts to clean up the lpc32xx udc driver and also repairs
> interrupt handling so hotplugging actually works. The design I tested
> that on uses an stotg04 instead of the usual isp1301 so support for that
> is also added.
>
> A bit more work is needed to get the RNDIS gadget driver to work.
>
> Alexandre Belloni (5):
> usb: gadget: udc: lpc32xx: simplify probe
> usb: gadget: udc: lpc32xx: simplify vbus handling
> usb: gadget: udc: lpc32xx: properly setup phy interrupts
> usb: gadget: udc: lpc32xx: add support for stotg04 phy
> usb: gadget: udc: lpc32xx: rework interrupt handling
>
> drivers/usb/gadget/udc/lpc32xx_udc.c | 167 +++++++++++----------------
> 1 file changed, 66 insertions(+), 101 deletions(-)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 0/5] usb: gadget: udc: lpc32xx: add stotg04 phy support
2019-05-13 11:32 ` [PATCH 0/5] usb: gadget: udc: lpc32xx: add stotg04 phy support James Grant
@ 2019-05-22 15:00 ` Sylvain Lemieux
0 siblings, 0 replies; 8+ messages in thread
From: Sylvain Lemieux @ 2019-05-22 15:00 UTC (permalink / raw)
To: James Grant
Cc: Alexandre Belloni, Felipe Balbi, Vladimir Zapolskiy,
Greg Kroah-Hartman, linux-usb, moderated list:ARM PORT,
linux-kernel
You can add my "Acked-by" on the 5 patches.
Acked-by: Sylvain Lemieux <slemieux.tyco@gmail.com>
On Mon, May 13, 2019 at 7:32 AM James Grant <jamesg@zaltys.org> wrote:
>
> Tested with a board containing LPC3250 SOC and STOTG04 PHY by using
> serial gadget.
>
> Needed patch "[PATCH] usb: gadget: udc: lpc32xx: allocate descriptor
> with GFP_ATOMIC" also.
>
> Tested-by: James Grant <jamesg@zaltys.org>
>
> Regards,
> James Grant.
>
> On 09/04/2019 14:09, Alexandre Belloni Wrote:
> > Hi,
> >
> > This series starts to clean up the lpc32xx udc driver and also repairs
> > interrupt handling so hotplugging actually works. The design I tested
> > that on uses an stotg04 instead of the usual isp1301 so support for that
> > is also added.
> >
> > A bit more work is needed to get the RNDIS gadget driver to work.
> >
> > Alexandre Belloni (5):
> > usb: gadget: udc: lpc32xx: simplify probe
> > usb: gadget: udc: lpc32xx: simplify vbus handling
> > usb: gadget: udc: lpc32xx: properly setup phy interrupts
> > usb: gadget: udc: lpc32xx: add support for stotg04 phy
> > usb: gadget: udc: lpc32xx: rework interrupt handling
> >
> > drivers/usb/gadget/udc/lpc32xx_udc.c | 167 +++++++++++----------------
> > 1 file changed, 66 insertions(+), 101 deletions(-)
^ permalink raw reply [flat|nested] 8+ messages in thread