2015-08-10 14:23:23

by Alexandre Belloni

[permalink] [raw]
Subject: [PATCH 0/4] USB: host: ohci-at91: cleanups

Hi,

Here are a few cleanups for ohci-at91. This is the fallout of AT91 now being DT
only.

Alexandre Belloni (4):
USB: host: ohci-at91: move at91_usbh_data definition in c file
USB: host: ohci-at91: depend on OF
USB: host: ohci-at91: merge ohci_at91_of_init in
ohci_hcd_at91_drv_probe
USB: host: ohci-at91: merge loops in ohci_hcd_at91_drv_probe

drivers/usb/host/Kconfig | 8 +-
drivers/usb/host/ohci-at91.c | 179 ++++++++++++++++--------------------
include/linux/platform_data/atmel.h | 12 ---
3 files changed, 85 insertions(+), 114 deletions(-)

--
2.1.4


2015-08-10 14:23:26

by Alexandre Belloni

[permalink] [raw]
Subject: [PATCH 1/4] USB: host: ohci-at91: move at91_usbh_data definition in c file

Move struct at91_usbh_data back in ohci-at91.c as this is the only user
left after switching all at91 platforms to DT only.

Signed-off-by: Alexandre Belloni <[email protected]>
---
drivers/usb/host/ohci-at91.c | 11 +++++++++++
include/linux/platform_data/atmel.h | 12 ------------
2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 15df00cceed9..72dc4f9e2a0f 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -36,6 +36,17 @@
#define hcd_to_ohci_at91_priv(h) \
((struct ohci_at91_priv *)hcd_to_ohci(h)->priv)

+#define AT91_MAX_USBH_PORTS 3
+struct at91_usbh_data {
+ int vbus_pin[AT91_MAX_USBH_PORTS]; /* port power-control pin */
+ int overcurrent_pin[AT91_MAX_USBH_PORTS];
+ u8 ports; /* number of ports on root hub */
+ u8 overcurrent_supported;
+ u8 vbus_pin_active_low[AT91_MAX_USBH_PORTS];
+ u8 overcurrent_status[AT91_MAX_USBH_PORTS];
+ u8 overcurrent_changed[AT91_MAX_USBH_PORTS];
+};
+
struct ohci_at91_priv {
struct clk *iclk;
struct clk *fclk;
diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
index 4b452c6a2f7b..527a85c61924 100644
--- a/include/linux/platform_data/atmel.h
+++ b/include/linux/platform_data/atmel.h
@@ -46,18 +46,6 @@ struct at91_cf_data {
#define AT91_IDE_SWAP_A0_A2 0x02
};

- /* USB Host */
-#define AT91_MAX_USBH_PORTS 3
-struct at91_usbh_data {
- int vbus_pin[AT91_MAX_USBH_PORTS]; /* port power-control pin */
- int overcurrent_pin[AT91_MAX_USBH_PORTS];
- u8 ports; /* number of ports on root hub */
- u8 overcurrent_supported;
- u8 vbus_pin_active_low[AT91_MAX_USBH_PORTS];
- u8 overcurrent_status[AT91_MAX_USBH_PORTS];
- u8 overcurrent_changed[AT91_MAX_USBH_PORTS];
-};
-
/* NAND / SmartMedia */
struct atmel_nand_data {
int enable_pin; /* chip enable */
--
2.1.4

2015-08-10 14:24:25

by Alexandre Belloni

[permalink] [raw]
Subject: [PATCH 2/4] USB: host: ohci-at91: depend on OF

Make the driver depend on CONFIG_OF and remove the now useless #ifdef

Also, fix the Kconfig indentation.

Signed-off-by: Alexandre Belloni <[email protected]>
---
drivers/usb/host/Kconfig | 8 ++++----
drivers/usb/host/ohci-at91.c | 9 +--------
2 files changed, 5 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 8afc3c1efdab..7ef56faf09bb 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -441,10 +441,10 @@ config USB_OHCI_HCD_PXA27X
PXA27x/PXA3xx chips.

config USB_OHCI_HCD_AT91
- tristate "Support for Atmel on-chip OHCI USB controller"
- depends on USB_OHCI_HCD && ARCH_AT91
- default y
- ---help---
+ tristate "Support for Atmel on-chip OHCI USB controller"
+ depends on USB_OHCI_HCD && ARCH_AT91 && OF
+ default y
+ ---help---
Enables support for the on-chip OHCI controller on
Atmel chips.

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 72dc4f9e2a0f..8e17d5ba26c6 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -442,7 +442,6 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
return IRQ_HANDLED;
}

-#ifdef CONFIG_OF
static const struct of_device_id at91_ohci_dt_ids[] = {
{ .compatible = "atmel,at91rm9200-ohci" },
{ /* sentinel */ }
@@ -492,12 +491,6 @@ static int ohci_at91_of_init(struct platform_device *pdev)

return 0;
}
-#else
-static int ohci_at91_of_init(struct platform_device *pdev)
-{
- return 0;
-}
-#endif

/*-------------------------------------------------------------------------*/

@@ -684,7 +677,7 @@ static struct platform_driver ohci_hcd_at91_driver = {
.driver = {
.name = "at91_ohci",
.pm = &ohci_hcd_at91_pm_ops,
- .of_match_table = of_match_ptr(at91_ohci_dt_ids),
+ .of_match_table = at91_ohci_dt_ids,
},
};

--
2.1.4

2015-08-10 14:23:37

by Alexandre Belloni

[permalink] [raw]
Subject: [PATCH 3/4] USB: host: ohci-at91: merge ohci_at91_of_init in ohci_hcd_at91_drv_probe

As device tree support is now mandatory, merge ohci_at91_of_init() in
ohci_hcd_at91_drv_probe().

Signed-off-by: Alexandre Belloni <[email protected]>
---
drivers/usb/host/ohci-at91.c | 145 +++++++++++++++++++------------------------
1 file changed, 63 insertions(+), 82 deletions(-)

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 8e17d5ba26c6..cdd91c551c7b 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -449,16 +449,17 @@ static const struct of_device_id at91_ohci_dt_ids[] = {

MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids);

-static int ohci_at91_of_init(struct platform_device *pdev)
+/*-------------------------------------------------------------------------*/
+
+static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
- int i, gpio, ret;
- enum of_gpio_flags flags;
struct at91_usbh_data *pdata;
- u32 ports;
-
- if (!np)
- return 0;
+ int i;
+ int gpio;
+ int ret;
+ enum of_gpio_flags flags;
+ u32 ports;

/* Right now device-tree probed devices don't get dma_mask set.
* Since shared usb code relies on it, set it here for now.
@@ -489,89 +490,69 @@ static int ohci_at91_of_init(struct platform_device *pdev)

pdev->dev.platform_data = pdata;

- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
-{
- struct at91_usbh_data *pdata;
- int i;
- int gpio;
- int ret;
-
- ret = ohci_at91_of_init(pdev);
- if (ret)
- return ret;
+ at91_for_each_port(i) {
+ /*
+ * do not configure PIO if not in relation with
+ * real USB port on board
+ */
+ if (i >= pdata->ports) {
+ pdata->vbus_pin[i] = -EINVAL;
+ pdata->overcurrent_pin[i] = -EINVAL;
+ break;
+ }

- pdata = dev_get_platdata(&pdev->dev);
+ if (!gpio_is_valid(pdata->vbus_pin[i]))
+ continue;
+ gpio = pdata->vbus_pin[i];

- if (pdata) {
- at91_for_each_port(i) {
- /*
- * do not configure PIO if not in relation with
- * real USB port on board
- */
- if (i >= pdata->ports) {
- pdata->vbus_pin[i] = -EINVAL;
- pdata->overcurrent_pin[i] = -EINVAL;
- break;
- }
+ ret = gpio_request(gpio, "ohci_vbus");
+ if (ret) {
+ dev_err(&pdev->dev,
+ "can't request vbus gpio %d\n", gpio);
+ continue;
+ }
+ ret = gpio_direction_output(gpio,
+ !pdata->vbus_pin_active_low[i]);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "can't put vbus gpio %d as output %d\n",
+ gpio, !pdata->vbus_pin_active_low[i]);
+ gpio_free(gpio);
+ continue;
+ }

- if (!gpio_is_valid(pdata->vbus_pin[i]))
- continue;
- gpio = pdata->vbus_pin[i];
+ ohci_at91_usb_set_power(pdata, i, 1);
+ }

- ret = gpio_request(gpio, "ohci_vbus");
- if (ret) {
- dev_err(&pdev->dev,
- "can't request vbus gpio %d\n", gpio);
- continue;
- }
- ret = gpio_direction_output(gpio,
- !pdata->vbus_pin_active_low[i]);
- if (ret) {
- dev_err(&pdev->dev,
- "can't put vbus gpio %d as output %d\n",
- gpio, !pdata->vbus_pin_active_low[i]);
- gpio_free(gpio);
- continue;
- }
+ at91_for_each_port(i) {
+ if (!gpio_is_valid(pdata->overcurrent_pin[i]))
+ continue;
+ gpio = pdata->overcurrent_pin[i];

- ohci_at91_usb_set_power(pdata, i, 1);
+ ret = gpio_request(gpio, "ohci_overcurrent");
+ if (ret) {
+ dev_err(&pdev->dev,
+ "can't request overcurrent gpio %d\n",
+ gpio);
+ continue;
}

- at91_for_each_port(i) {
- if (!gpio_is_valid(pdata->overcurrent_pin[i]))
- continue;
- gpio = pdata->overcurrent_pin[i];
-
- ret = gpio_request(gpio, "ohci_overcurrent");
- if (ret) {
- dev_err(&pdev->dev,
- "can't request overcurrent gpio %d\n",
- gpio);
- continue;
- }
-
- ret = gpio_direction_input(gpio);
- if (ret) {
- dev_err(&pdev->dev,
- "can't configure overcurrent gpio %d as input\n",
- gpio);
- gpio_free(gpio);
- continue;
- }
+ ret = gpio_direction_input(gpio);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "can't configure overcurrent gpio %d as input\n",
+ gpio);
+ gpio_free(gpio);
+ continue;
+ }

- ret = request_irq(gpio_to_irq(gpio),
- ohci_hcd_at91_overcurrent_irq,
- IRQF_SHARED, "ohci_overcurrent", pdev);
- if (ret) {
- gpio_free(gpio);
- dev_err(&pdev->dev,
- "can't get gpio IRQ for overcurrent\n");
- }
+ ret = request_irq(gpio_to_irq(gpio),
+ ohci_hcd_at91_overcurrent_irq,
+ IRQF_SHARED, "ohci_overcurrent", pdev);
+ if (ret) {
+ gpio_free(gpio);
+ dev_err(&pdev->dev,
+ "can't get gpio IRQ for overcurrent\n");
}
}

--
2.1.4

2015-08-10 14:23:34

by Alexandre Belloni

[permalink] [raw]
Subject: [PATCH 4/4] USB: host: ohci-at91: merge loops in ohci_hcd_at91_drv_probe

ohci_hcd_at91_drv_probe() has four at91_for_each_port. They can be merged
into two loops without changing the driver behaviour.

Signed-off-by: Alexandre Belloni <[email protected]>
---
drivers/usb/host/ohci-at91.c | 34 ++++++++++++++++------------------
1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index cdd91c551c7b..342ffd140122 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -477,33 +477,21 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
pdata->ports = ports;

at91_for_each_port(i) {
- gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", i, &flags);
- pdata->vbus_pin[i] = gpio;
- if (!gpio_is_valid(gpio))
- continue;
- pdata->vbus_pin_active_low[i] = flags & OF_GPIO_ACTIVE_LOW;
- }
-
- at91_for_each_port(i)
- pdata->overcurrent_pin[i] =
- of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
-
- pdev->dev.platform_data = pdata;
-
- at91_for_each_port(i) {
/*
* do not configure PIO if not in relation with
* real USB port on board
*/
if (i >= pdata->ports) {
pdata->vbus_pin[i] = -EINVAL;
- pdata->overcurrent_pin[i] = -EINVAL;
- break;
+ continue;
}

- if (!gpio_is_valid(pdata->vbus_pin[i]))
+ gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", i,
+ &flags);
+ pdata->vbus_pin[i] = gpio;
+ if (!gpio_is_valid(gpio))
continue;
- gpio = pdata->vbus_pin[i];
+ pdata->vbus_pin_active_low[i] = flags & OF_GPIO_ACTIVE_LOW;

ret = gpio_request(gpio, "ohci_vbus");
if (ret) {
@@ -525,6 +513,14 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
}

at91_for_each_port(i) {
+ if (i >= pdata->ports) {
+ pdata->overcurrent_pin[i] = -EINVAL;
+ continue;
+ }
+
+ pdata->overcurrent_pin[i] =
+ of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
+
if (!gpio_is_valid(pdata->overcurrent_pin[i]))
continue;
gpio = pdata->overcurrent_pin[i];
@@ -556,6 +552,8 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
}
}

+ pdev->dev.platform_data = pdata;
+
device_init_wakeup(&pdev->dev, 1);
return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
}
--
2.1.4

2015-08-12 21:08:21

by Alan Stern

[permalink] [raw]
Subject: Re: [PATCH 0/4] USB: host: ohci-at91: cleanups

On Mon, 10 Aug 2015, Alexandre Belloni wrote:

> Hi,
>
> Here are a few cleanups for ohci-at91. This is the fallout of AT91 now being DT
> only.
>
> Alexandre Belloni (4):
> USB: host: ohci-at91: move at91_usbh_data definition in c file
> USB: host: ohci-at91: depend on OF
> USB: host: ohci-at91: merge ohci_at91_of_init in
> ohci_hcd_at91_drv_probe
> USB: host: ohci-at91: merge loops in ohci_hcd_at91_drv_probe
>
> drivers/usb/host/Kconfig | 8 +-
> drivers/usb/host/ohci-at91.c | 179 ++++++++++++++++--------------------
> include/linux/platform_data/atmel.h | 12 ---
> 3 files changed, 85 insertions(+), 114 deletions(-)

Acked-by: Alan Stern <[email protected]>

2015-12-01 17:17:27

by Peter Rosin

[permalink] [raw]
Subject: Regression, was [PATCH 4/4] USB: host: ohci-at91: merge loops in ohci_hcd_at91_drv_probe

Hi!

Alexandre Belloni wrote:
> ohci_hcd_at91_drv_probe() has four at91_for_each_port. They can be merged
> into two loops without changing the driver behaviour.

Not so much, I bisected the following panic to the commit matching this patch
(e4df92279fd9e01532f65e5ba397877799ed6252).

Reverting that commit on top of 4.3 fixes things for me.

Cheers,
Peter

...
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
ohci-atmel: OHCI Atmel driver
Unable to handle kernel NULL pointer dereference at virtual address 0000000c
pgd = c0004000
[0000000c] *pgd=00000000
Internal error: Oops: 5 [#1] ARM
Modules linked in:
CPU: 0 PID: 1 Comm: swapper Not tainted 4.2.0-rc6+ #5
Hardware name: Atmel SAMA5
task: c3825ac0 ti: c3826000 task.ti: c3826000
PC is at ohci_hcd_at91_overcurrent_irq+0x18/0xe8
LR is at handle_irq_event_percpu+0x78/0x140
pc : [<c02f5084>] lr : [<c00433b0>] psr: 40000193
sp : c3827d08 ip : c3000e34 fp : c3a016dc
r10: c06e8bbd r9 : c3941880 r8 : 0000007f
r7 : c392be00 r6 : 00000000 r5 : 00000008 r4 : 00000000
r3 : c02f506c r2 : c3941880 r1 : c392be00 r0 : 0000007f
Flags: nZcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: 10c53c7d Table: 20004059 DAC: 00000015
Process swapper (pid: 1, stack limit = 0xc3826208)
Stack: (0xc3827d08 to 0xc3828000)
7d00: c3a01600 c383fb10 00000000 00000000 0000007f c00433b0
7d20: 00000000 ffffffff c3941880 c383fb10 c4856648 c383fb10 c485664c c3802460
7d40: c38a6044 c00434a4 c3941880 c00458b8 0000007f c0042bc4 0000000f c01fe4ac
7d60: ff0a0110 00008000 00000028 00000000 00000000 00000001 c3802200 00000000
7d80: 0000007f c0042bc4 c06c91d4 c0042dec c004451c 60000113 ffffffff c3827ddc
7da0: 60000113 c0013500 c3941880 c3a01600 00000000 00000000 c3941880 0000007f
7dc0: c3a01600 00000000 60000113 00000000 0000007f c3a016dc 00000000 c3827df0
7de0: c00446b4 c004451c 60000113 ffffffff c383fb10 c00914d0 c3a01600 00000080
7e00: c3941880 c02f506c c392be00 c0044954 c392be00 00000000 c392be10 c3f77690
7e20: c3a016d0 c060d1e4 00000000 c02f5a0c c060d1e4 c392be00 0000004f 00000000
7e40: 00000001 00000001 c3927178 c070a458 c392be10 c06d7bfc fffffdfb c06d7bfc
7e60: 00000000 c06b0f68 00000000 c02670ec c02670a8 c070a458 c392be10 00000000
7e80: c06ecd78 c02655b4 c02657f4 00000000 c06ce538 c392be10 c06d7bfc c392be44
7ea0: 00000000 c06ce538 00000096 c0265880 00000000 c06d7bfc c02657f4 c0263880
7ec0: c383ea4c c39168b0 c06d7bfc c39df280 c06ecca0 c0264b80 c060d318 c3a017c0
7ee0: c06d7bfc c06be860 c3a017c0 c06a1468 00000000 c0266078 c0267050 c06be860
7f00: c06be860 c00096c8 c3807280 c06fc48c c3839100 c04d9470 00000000 00000000
7f20: 00004140 c00dff9c 00000000 00000096 c3ffca15 c0031e54 00000000 c06b0f44
7f40: c0612f0c c3ffcab1 00000006 00000006 00000000 00000000 c06b84b4 00000006
7f60: c06b0f60 c06f4140 c06f4140 c06b0f68 00000000 c068bda4 00000006 00000006
7f80: 00000000 c068b5b0 00000000 c04d06ec 00000000 00000000 00000000 00000000
7fa0: 00000000 c04d06f4 00000000 c000ff68 00000000 00000000 00000000 00000000
7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fe0: 00000000 00000000 00000000 00000000 00000013 00000000 8aaaaaaa aaaaaaaa
[<c02f5084>] (ohci_hcd_at91_overcurrent_irq) from [<c00433b0>] (handle_irq_event_percpu+0x78/0x140)
[<c00433b0>] (handle_irq_event_percpu) from [<c00434a4>] (handle_irq_event+0x2c/0x40)
[<c00434a4>] (handle_irq_event) from [<c00458b8>] (handle_simple_irq+0x6c/0x80)
[<c00458b8>] (handle_simple_irq) from [<c0042bc4>] (generic_handle_irq+0x2c/0x3c)
[<c0042bc4>] (generic_handle_irq) from [<c01fe4ac>] (gpio_irq_handler+0xa4/0x12c)
[<c01fe4ac>] (gpio_irq_handler) from [<c0042bc4>] (generic_handle_irq+0x2c/0x3c)
[<c0042bc4>] (generic_handle_irq) from [<c0042dec>] (__handle_domain_irq+0x54/0xa8)
[<c0042dec>] (__handle_domain_irq) from [<c0013500>] (__irq_svc+0x40/0x54)
[<c0013500>] (__irq_svc) from [<c004451c>] (__setup_irq+0x248/0x530)
[<c004451c>] (__setup_irq) from [<c0044954>] (request_threaded_irq+0xc4/0x144)
[<c0044954>] (request_threaded_irq) from [<c02f5a0c>] (ohci_hcd_at91_drv_probe+0x460/0x518)
[<c02f5a0c>] (ohci_hcd_at91_drv_probe) from [<c02670ec>] (platform_drv_probe+0x44/0xa4)
[<c02670ec>] (platform_drv_probe) from [<c02655b4>] (driver_probe_device+0x1fc/0x43c)
[<c02655b4>] (driver_probe_device) from [<c0265880>] (__driver_attach+0x8c/0x90)
[<c0265880>] (__driver_attach) from [<c0263880>] (bus_for_each_dev+0x6c/0xa0)
[<c0263880>] (bus_for_each_dev) from [<c0264b80>] (bus_add_driver+0x1d0/0x268)
[<c0264b80>] (bus_add_driver) from [<c0266078>] (driver_register+0x78/0xf8)
[<c0266078>] (driver_register) from [<c00096c8>] (do_one_initcall+0xb8/0x1f0)
[<c00096c8>] (do_one_initcall) from [<c068bda4>] (kernel_init_freeable+0x138/0x1d8)
[<c068bda4>] (kernel_init_freeable) from [<c04d06f4>] (kernel_init+0x8/0xe8)
[<c04d06f4>] (kernel_init) from [<c000ff68>] (ret_from_fork+0x14/0x2c)
Code: e5916058 e1a08000 e3a04000 e2865008 (e5b50004)
---[ end trace e66fbc480972ac43 ]---
Kernel panic - not syncing: Fatal exception in interrupt
---[ end Kernel panic - not syncing: Fatal exception in interrupt

2015-12-02 18:20:06

by Alexandre Belloni

[permalink] [raw]
Subject: Re: Regression, was [PATCH 4/4] USB: host: ohci-at91: merge loops in ohci_hcd_at91_drv_probe

Hi Peter,

On 01/12/2015 at 18:17:16 +0100, Peter Rosin wrote :
> [<c02f5084>] (ohci_hcd_at91_overcurrent_irq) from [<c00433b0>] (handle_irq_event_percpu+0x78/0x140)
> [<c00433b0>] (handle_irq_event_percpu) from [<c00434a4>] (handle_irq_event+0x2c/0x40)
> [<c00434a4>] (handle_irq_event) from [<c00458b8>] (handle_simple_irq+0x6c/0x80)
> [<c00458b8>] (handle_simple_irq) from [<c0042bc4>] (generic_handle_irq+0x2c/0x3c)
> [<c0042bc4>] (generic_handle_irq) from [<c01fe4ac>] (gpio_irq_handler+0xa4/0x12c)
> [<c01fe4ac>] (gpio_irq_handler) from [<c0042bc4>] (generic_handle_irq+0x2c/0x3c)
> [<c0042bc4>] (generic_handle_irq) from [<c0042dec>] (__handle_domain_irq+0x54/0xa8)
> [<c0042dec>] (__handle_domain_irq) from [<c0013500>] (__irq_svc+0x40/0x54)
> [<c0013500>] (__irq_svc) from [<c004451c>] (__setup_irq+0x248/0x530)
> [<c004451c>] (__setup_irq) from [<c0044954>] (request_threaded_irq+0xc4/0x144)
> [<c0044954>] (request_threaded_irq) from [<c02f5a0c>] (ohci_hcd_at91_drv_probe+0x460/0x518)
> [<c02f5a0c>] (ohci_hcd_at91_drv_probe) from [<c02670ec>] (platform_drv_probe+0x44/0xa4)
> [<c02670ec>] (platform_drv_probe) from [<c02655b4>] (driver_probe_device+0x1fc/0x43c)
> [<c02655b4>] (driver_probe_device) from [<c0265880>] (__driver_attach+0x8c/0x90)
> [<c0265880>] (__driver_attach) from [<c0263880>] (bus_for_each_dev+0x6c/0xa0)
> [<c0263880>] (bus_for_each_dev) from [<c0264b80>] (bus_add_driver+0x1d0/0x268)
> [<c0264b80>] (bus_add_driver) from [<c0266078>] (driver_register+0x78/0xf8)
> [<c0266078>] (driver_register) from [<c00096c8>] (do_one_initcall+0xb8/0x1f0)
> [<c00096c8>] (do_one_initcall) from [<c068bda4>] (kernel_init_freeable+0x138/0x1d8)
> [<c068bda4>] (kernel_init_freeable) from [<c04d06f4>] (kernel_init+0x8/0xe8)
> [<c04d06f4>] (kernel_init) from [<c000ff68>] (ret_from_fork+0x14/0x2c)
> Code: e5916058 e1a08000 e3a04000 e2865008 (e5b50004)
> ---[ end trace e66fbc480972ac43 ]---
> Kernel panic - not syncing: Fatal exception in interrupt
> ---[ end Kernel panic - not syncing: Fatal exception in interrupt

I think I understood what happens. Can you try the following patch?

8<------
>From 402f8444bc92d218edc63dcc3c87459981a56c31 Mon Sep 17 00:00:00 2001
From: Alexandre Belloni <[email protected]>
Date: Wed, 2 Dec 2015 18:49:34 +0100
Subject: [PATCH] USB: host: ohci-at91: fix a crash in
ohci_hcd_at91_overcurrent_irq

Signed-off-by: Alexandre Belloni <[email protected]>
---
drivers/usb/host/ohci-at91.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 342ffd140122..8c6e15bd6ff0 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -473,6 +473,8 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
if (!pdata)
return -ENOMEM;

+ pdev->dev.platform_data = pdata;
+
if (!of_property_read_u32(np, "num-ports", &ports))
pdata->ports = ports;

@@ -483,6 +485,7 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
*/
if (i >= pdata->ports) {
pdata->vbus_pin[i] = -EINVAL;
+ pdata->overcurrent_pin[i] = -EINVAL;
continue;
}

@@ -513,10 +516,8 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
}

at91_for_each_port(i) {
- if (i >= pdata->ports) {
- pdata->overcurrent_pin[i] = -EINVAL;
- continue;
- }
+ if (i >= pdata->ports)
+ break;

pdata->overcurrent_pin[i] =
of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
@@ -552,8 +553,6 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
}
}

- pdev->dev.platform_data = pdata;
-
device_init_wakeup(&pdev->dev, 1);
return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
}
--
2.5.0

2015-12-02 19:29:43

by Peter Rosin

[permalink] [raw]
Subject: Re: Regression, was [PATCH 4/4] USB: host: ohci-at91: merge loops in ohci_hcd_at91_drv_probe

Hi Alexandre,

On 2015-12-02 19:20, Alexandre Belloni wrote:
> Hi Peter,
>
> On 01/12/2015 at 18:17:16 +0100, Peter Rosin wrote :
>> [<c02f5084>] (ohci_hcd_at91_overcurrent_irq) from [<c00433b0>] (handle_irq_event_percpu+0x78/0x140)
>> [<c00433b0>] (handle_irq_event_percpu) from [<c00434a4>] (handle_irq_event+0x2c/0x40)
>> [<c00434a4>] (handle_irq_event) from [<c00458b8>] (handle_simple_irq+0x6c/0x80)
>> [<c00458b8>] (handle_simple_irq) from [<c0042bc4>] (generic_handle_irq+0x2c/0x3c)
>> [<c0042bc4>] (generic_handle_irq) from [<c01fe4ac>] (gpio_irq_handler+0xa4/0x12c)
>> [<c01fe4ac>] (gpio_irq_handler) from [<c0042bc4>] (generic_handle_irq+0x2c/0x3c)
>> [<c0042bc4>] (generic_handle_irq) from [<c0042dec>] (__handle_domain_irq+0x54/0xa8)
>> [<c0042dec>] (__handle_domain_irq) from [<c0013500>] (__irq_svc+0x40/0x54)
>> [<c0013500>] (__irq_svc) from [<c004451c>] (__setup_irq+0x248/0x530)
>> [<c004451c>] (__setup_irq) from [<c0044954>] (request_threaded_irq+0xc4/0x144)
>> [<c0044954>] (request_threaded_irq) from [<c02f5a0c>] (ohci_hcd_at91_drv_probe+0x460/0x518)
>> [<c02f5a0c>] (ohci_hcd_at91_drv_probe) from [<c02670ec>] (platform_drv_probe+0x44/0xa4)
>> [<c02670ec>] (platform_drv_probe) from [<c02655b4>] (driver_probe_device+0x1fc/0x43c)
>> [<c02655b4>] (driver_probe_device) from [<c0265880>] (__driver_attach+0x8c/0x90)
>> [<c0265880>] (__driver_attach) from [<c0263880>] (bus_for_each_dev+0x6c/0xa0)
>> [<c0263880>] (bus_for_each_dev) from [<c0264b80>] (bus_add_driver+0x1d0/0x268)
>> [<c0264b80>] (bus_add_driver) from [<c0266078>] (driver_register+0x78/0xf8)
>> [<c0266078>] (driver_register) from [<c00096c8>] (do_one_initcall+0xb8/0x1f0)
>> [<c00096c8>] (do_one_initcall) from [<c068bda4>] (kernel_init_freeable+0x138/0x1d8)
>> [<c068bda4>] (kernel_init_freeable) from [<c04d06f4>] (kernel_init+0x8/0xe8)
>> [<c04d06f4>] (kernel_init) from [<c000ff68>] (ret_from_fork+0x14/0x2c)
>> Code: e5916058 e1a08000 e3a04000 e2865008 (e5b50004)
>> ---[ end trace e66fbc480972ac43 ]---
>> Kernel panic - not syncing: Fatal exception in interrupt
>> ---[ end Kernel panic - not syncing: Fatal exception in interrupt
>
> I think I understood what happens. Can you try the following patch?

Seems to work here. Excellent!

> 8<------
> From 402f8444bc92d218edc63dcc3c87459981a56c31 Mon Sep 17 00:00:00 2001
> From: Alexandre Belloni <[email protected]>
> Date: Wed, 2 Dec 2015 18:49:34 +0100
> Subject: [PATCH] USB: host: ohci-at91: fix a crash in
> ohci_hcd_at91_overcurrent_irq
>
> Signed-off-by: Alexandre Belloni <[email protected]>

Reported-by: Peter Rosin <[email protected]>
Tested-by: Peter Rosin <[email protected]>

(and bisected-by if anyone cares...)

Cheers,
Peter