Skip to content

Commit

Permalink
Merge pull request #1086 from notro/fiq
Browse files Browse the repository at this point in the history
dwc_otg: Add ARCH_BCM2835 support
  • Loading branch information
pelwell committed Jul 24, 2015
2 parents 193a0ca + cdd8699 commit ab1bc20
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 10 deletions.
8 changes: 5 additions & 3 deletions arch/arm/boot/dts/bcm2835.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,11 @@
};

usb: usb@7e980000 {
compatible = "brcm,bcm2835-usb";
reg = <0x7e980000 0x10000>;
interrupts = <1 9>;
compatible = "brcm,bcm2708-usb";
reg = <0x7e980000 0x10000>,
<0x7e006000 0x1000>;
interrupts = <2 0>,
<1 9>;
};

arm-pmu {
Expand Down
1 change: 1 addition & 0 deletions arch/arm/configs/bcm2835_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,7 @@ CONFIG_USB_HIDDEV=y
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_MON=m
CONFIG_USB_DWCOTG=y
CONFIG_USB_PRINTER=m
CONFIG_USB_STORAGE=y
CONFIG_USB_STORAGE_REALTEK=m
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-bcm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ config ARCH_BCM2835
select ARM_ERRATA_411920
select ARM_TIMER_SP804
select CLKSRC_OF
select FIQ
select PINCTRL
select PINCTRL_BCM2835
help
Expand Down
53 changes: 47 additions & 6 deletions drivers/irqchip/irq-bcm2835.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
#include "irqchip.h"

/* Put the bank and irq (32 bits) into the hwirq */
#define MAKE_HWIRQ(b, n) ((b << 5) | (n))
#define MAKE_HWIRQ(b, n) (((b) << 5) | (n))
#define HWIRQ_BANK(i) (i >> 5)
#define HWIRQ_BIT(i) BIT(i & 0x1f)

Expand All @@ -72,9 +72,13 @@
| SHORTCUT1_MASK | SHORTCUT2_MASK)

#define REG_FIQ_CONTROL 0x0c
#define REG_FIQ_ENABLE 0x80
#define REG_FIQ_DISABLE 0

#define NR_BANKS 3
#define IRQS_PER_BANK 32
#define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0)
#define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0))

static int reg_pending[] __initconst = { 0x00, 0x04, 0x08 };
static int reg_enable[] __initconst = { 0x18, 0x10, 0x14 };
Expand All @@ -98,14 +102,38 @@ static struct armctrl_ic intc __read_mostly;
static void __exception_irq_entry bcm2835_handle_irq(
struct pt_regs *regs);

static inline unsigned int hwirq_to_fiq(unsigned long hwirq)
{
hwirq -= NUMBER_IRQS;
/*
* The hwirq numbering used in this driver is:
* BASE (0-7) GPU1 (32-63) GPU2 (64-95).
* This differ from the one used in the FIQ register:
* GPU1 (0-31) GPU2 (32-63) BASE (64-71)
*/
if (hwirq >= 32)
return hwirq - 32;

return hwirq + 64;
}

static void armctrl_mask_irq(struct irq_data *d)
{
writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]);
if (d->hwirq >= NUMBER_IRQS)
writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL);
else
writel_relaxed(HWIRQ_BIT(d->hwirq),
intc.disable[HWIRQ_BANK(d->hwirq)]);
}

static void armctrl_unmask_irq(struct irq_data *d)
{
writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]);
if (d->hwirq >= NUMBER_IRQS)
writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq),
intc.base + REG_FIQ_CONTROL);
else
writel_relaxed(HWIRQ_BIT(d->hwirq),
intc.enable[HWIRQ_BANK(d->hwirq)]);
}

static struct irq_chip armctrl_chip = {
Expand Down Expand Up @@ -150,8 +178,9 @@ static int __init armctrl_of_init(struct device_node *node,
panic("%s: unable to map IC registers\n",
node->full_name);

intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0),
&armctrl_ops, NULL);
intc.base = base;
intc.domain = irq_domain_add_linear(node, NUMBER_IRQS * 2,
&armctrl_ops, NULL);
if (!intc.domain)
panic("%s: unable to create IRQ domain\n", node->full_name);

Expand All @@ -168,8 +197,20 @@ static int __init armctrl_of_init(struct device_node *node,
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}

set_handle_irq(bcm2835_handle_irq);

/* Make a duplicate irq range which is used to enable FIQ */
for (b = 0; b < NR_BANKS; b++) {
for (i = 0; i < bank_irqs[b]; i++) {
irq = irq_create_mapping(intc.domain,
MAKE_HWIRQ(b, i) + NUMBER_IRQS);
BUG_ON(irq <= 0);
irq_set_chip(irq, &armctrl_chip);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}
init_FIQ(FIQ_START);

return 0;
}

Expand Down
1 change: 1 addition & 0 deletions drivers/usb/host/dwc_otg/dwc_otg_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,7 @@ static int dwc_otg_driver_probe(

memset(dwc_otg_device, 0, sizeof(*dwc_otg_device));
dwc_otg_device->os_dep.reg_offset = 0xFFFFFFFF;
dwc_otg_device->os_dep.platformdev = _dev;

/*
* Map the DWC_otg Core memory into virtual address space.
Expand Down
1 change: 0 additions & 1 deletion drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
#include "dwc_otg_regs.h"

#include <linux/jiffies.h>
#include <mach/hardware.h>
#include <asm/fiq.h>


Expand Down
4 changes: 4 additions & 0 deletions drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,11 @@ static void hcd_init_fiq(void *cookie)
DWC_WARN("MPHI periph has NOT been enabled");
#endif
// Enable FIQ interrupt from USB peripheral
#ifdef CONFIG_ARCH_BCM2835
enable_fiq(platform_get_irq(otg_dev->os_dep.platformdev, 1));
#else
enable_fiq(INTERRUPT_VC_USB);
#endif
local_fiq_enable();
}

Expand Down

0 comments on commit ab1bc20

Please sign in to comment.