mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 19:26:25 +00:00
Merge commit 'kumar/next' into merge
This commit is contained in:
commit
2593f939a5
8 changed files with 247 additions and 16 deletions
42
Documentation/powerpc/dts-bindings/fsl/mpic.txt
Normal file
42
Documentation/powerpc/dts-bindings/fsl/mpic.txt
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
* OpenPIC and its interrupt numbers on Freescale's e500/e600 cores
|
||||||
|
|
||||||
|
The OpenPIC specification does not specify which interrupt source has to
|
||||||
|
become which interrupt number. This is up to the software implementation
|
||||||
|
of the interrupt controller. The only requirement is that every
|
||||||
|
interrupt source has to have an unique interrupt number / vector number.
|
||||||
|
To accomplish this the current implementation assigns the number zero to
|
||||||
|
the first source, the number one to the second source and so on until
|
||||||
|
all interrupt sources have their unique number.
|
||||||
|
Usually the assigned vector number equals the interrupt number mentioned
|
||||||
|
in the documentation for a given core / CPU. This is however not true
|
||||||
|
for the e500 cores (MPC85XX CPUs) where the documentation distinguishes
|
||||||
|
between internal and external interrupt sources and starts counting at
|
||||||
|
zero for both of them.
|
||||||
|
|
||||||
|
So what to write for external interrupt source X or internal interrupt
|
||||||
|
source Y into the device tree? Here is an example:
|
||||||
|
|
||||||
|
The memory map for the interrupt controller in the MPC8544[0] shows,
|
||||||
|
that the first interrupt source starts at 0x5_0000 (PIC Register Address
|
||||||
|
Map-Interrupt Source Configuration Registers). This source becomes the
|
||||||
|
number zero therefore:
|
||||||
|
External interrupt 0 = interrupt number 0
|
||||||
|
External interrupt 1 = interrupt number 1
|
||||||
|
External interrupt 2 = interrupt number 2
|
||||||
|
...
|
||||||
|
Every interrupt number allocates 0x20 bytes register space. So to get
|
||||||
|
its number it is sufficient to shift the lower 16bits to right by five.
|
||||||
|
So for the external interrupt 10 we have:
|
||||||
|
0x0140 >> 5 = 10
|
||||||
|
|
||||||
|
After the external sources, the internal sources follow. The in core I2C
|
||||||
|
controller on the MPC8544 for instance has the internal source number
|
||||||
|
27. Oo obtain its interrupt number we take the lower 16bits of its memory
|
||||||
|
address (0x5_0560) and shift it right:
|
||||||
|
0x0560 >> 5 = 43
|
||||||
|
|
||||||
|
Therefore the I2C device node for the MPC8544 CPU has to have the
|
||||||
|
interrupt number 43 specified in the device tree.
|
||||||
|
|
||||||
|
[0] MPC8544E PowerQUICCTM III, Integrated Host Processor Family Reference Manual
|
||||||
|
MPC8544ERM Rev. 1 10/2007
|
|
@ -204,6 +204,7 @@
|
||||||
interrupt-parent = <&ipic>;
|
interrupt-parent = <&ipic>;
|
||||||
tbi-handle = <&tbi0>;
|
tbi-handle = <&tbi0>;
|
||||||
phy-handle = < &phy0 >;
|
phy-handle = < &phy0 >;
|
||||||
|
fsl,magic-packet;
|
||||||
|
|
||||||
mdio@520 {
|
mdio@520 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
|
@ -246,6 +247,7 @@
|
||||||
interrupt-parent = <&ipic>;
|
interrupt-parent = <&ipic>;
|
||||||
tbi-handle = <&tbi1>;
|
tbi-handle = <&tbi1>;
|
||||||
phy-handle = < &phy1 >;
|
phy-handle = < &phy1 >;
|
||||||
|
fsl,magic-packet;
|
||||||
|
|
||||||
mdio@520 {
|
mdio@520 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
|
@ -309,6 +311,22 @@
|
||||||
interrupt-parent = <&ipic>;
|
interrupt-parent = <&ipic>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gtm1: timer@500 {
|
||||||
|
compatible = "fsl,mpc8315-gtm", "fsl,gtm";
|
||||||
|
reg = <0x500 0x100>;
|
||||||
|
interrupts = <90 8 78 8 84 8 72 8>;
|
||||||
|
interrupt-parent = <&ipic>;
|
||||||
|
clock-frequency = <133333333>;
|
||||||
|
};
|
||||||
|
|
||||||
|
timer@600 {
|
||||||
|
compatible = "fsl,mpc8315-gtm", "fsl,gtm";
|
||||||
|
reg = <0x600 0x100>;
|
||||||
|
interrupts = <91 8 79 8 85 8 73 8>;
|
||||||
|
interrupt-parent = <&ipic>;
|
||||||
|
clock-frequency = <133333333>;
|
||||||
|
};
|
||||||
|
|
||||||
/* IPIC
|
/* IPIC
|
||||||
* interrupts cell = <intr #, sense>
|
* interrupts cell = <intr #, sense>
|
||||||
* sense values match linux IORESOURCE_IRQ_* defines:
|
* sense values match linux IORESOURCE_IRQ_* defines:
|
||||||
|
@ -337,6 +355,15 @@
|
||||||
0x59 0x8>;
|
0x59 0x8>;
|
||||||
interrupt-parent = < &ipic >;
|
interrupt-parent = < &ipic >;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pmc: power@b00 {
|
||||||
|
compatible = "fsl,mpc8315-pmc", "fsl,mpc8313-pmc",
|
||||||
|
"fsl,mpc8349-pmc";
|
||||||
|
reg = <0xb00 0x100 0xa00 0x100>;
|
||||||
|
interrupts = <80 8>;
|
||||||
|
interrupt-parent = <&ipic>;
|
||||||
|
fsl,mpc8313-wakeup-timer = <>m1>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
pci0: pci@e0008500 {
|
pci0: pci@e0008500 {
|
||||||
|
|
|
@ -63,6 +63,24 @@
|
||||||
reg = <0x200 0x100>;
|
reg = <0x200 0x100>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gpio1: gpio-controller@c00 {
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
compatible = "fsl,mpc8349-gpio";
|
||||||
|
reg = <0xc00 0x100>;
|
||||||
|
interrupts = <74 0x8>;
|
||||||
|
interrupt-parent = <&ipic>;
|
||||||
|
gpio-controller;
|
||||||
|
};
|
||||||
|
|
||||||
|
gpio2: gpio-controller@d00 {
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
compatible = "fsl,mpc8349-gpio";
|
||||||
|
reg = <0xd00 0x100>;
|
||||||
|
interrupts = <75 0x8>;
|
||||||
|
interrupt-parent = <&ipic>;
|
||||||
|
gpio-controller;
|
||||||
|
};
|
||||||
|
|
||||||
i2c@3000 {
|
i2c@3000 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
@ -72,6 +90,12 @@
|
||||||
interrupts = <14 0x8>;
|
interrupts = <14 0x8>;
|
||||||
interrupt-parent = <&ipic>;
|
interrupt-parent = <&ipic>;
|
||||||
dfsrr;
|
dfsrr;
|
||||||
|
|
||||||
|
eeprom: at24@50 {
|
||||||
|
compatible = "st-micro,24c256";
|
||||||
|
reg = <0x50>;
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
i2c@3100 {
|
i2c@3100 {
|
||||||
|
@ -91,6 +115,25 @@
|
||||||
interrupt-parent = <&ipic>;
|
interrupt-parent = <&ipic>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pcf1: iexp@38 {
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
compatible = "ti,pcf8574a";
|
||||||
|
reg = <0x38>;
|
||||||
|
gpio-controller;
|
||||||
|
};
|
||||||
|
|
||||||
|
pcf2: iexp@39 {
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
compatible = "ti,pcf8574a";
|
||||||
|
reg = <0x39>;
|
||||||
|
gpio-controller;
|
||||||
|
};
|
||||||
|
|
||||||
|
spd: at24@51 {
|
||||||
|
compatible = "at24,spd";
|
||||||
|
reg = <0x51>;
|
||||||
|
};
|
||||||
|
|
||||||
mcu_pio: mcu@a {
|
mcu_pio: mcu@a {
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
compatible = "fsl,mc9s08qg8-mpc8349emitx",
|
compatible = "fsl,mc9s08qg8-mpc8349emitx",
|
||||||
|
@ -275,6 +318,24 @@
|
||||||
reg = <0x700 0x100>;
|
reg = <0x700 0x100>;
|
||||||
device_type = "ipic";
|
device_type = "ipic";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gpio-leds {
|
||||||
|
compatible = "gpio-leds";
|
||||||
|
|
||||||
|
green {
|
||||||
|
label = "Green";
|
||||||
|
gpios = <&pcf1 0 1>;
|
||||||
|
linux,default-trigger = "heartbeat";
|
||||||
|
};
|
||||||
|
|
||||||
|
yellow {
|
||||||
|
label = "Yellow";
|
||||||
|
gpios = <&pcf1 1 1>;
|
||||||
|
/* linux,default-trigger = "heartbeat"; */
|
||||||
|
default-state = "on";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pci0: pci@e0008500 {
|
pci0: pci@e0008500 {
|
||||||
|
@ -331,7 +392,26 @@
|
||||||
compatible = "fsl,mpc8349e-localbus",
|
compatible = "fsl,mpc8349e-localbus",
|
||||||
"fsl,pq2pro-localbus";
|
"fsl,pq2pro-localbus";
|
||||||
reg = <0xe0005000 0xd8>;
|
reg = <0xe0005000 0xd8>;
|
||||||
ranges = <0x3 0x0 0xf0000000 0x210>;
|
ranges = <0x0 0x0 0xfe000000 0x1000000 /* flash */
|
||||||
|
0x1 0x0 0xf8000000 0x20000 /* VSC 7385 */
|
||||||
|
0x2 0x0 0xf9000000 0x200000 /* exp slot */
|
||||||
|
0x3 0x0 0xf0000000 0x210>; /* CF slot */
|
||||||
|
|
||||||
|
flash@0,0 {
|
||||||
|
compatible = "cfi-flash";
|
||||||
|
reg = <0x0 0x0 0x800000>;
|
||||||
|
bank-width = <2>;
|
||||||
|
device-width = <1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
flash@0,800000 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
compatible = "cfi-flash";
|
||||||
|
reg = <0x0 0x800000 0x800000>;
|
||||||
|
bank-width = <2>;
|
||||||
|
device-width = <1>;
|
||||||
|
};
|
||||||
|
|
||||||
pata@3,0 {
|
pata@3,0 {
|
||||||
compatible = "fsl,mpc8349emitx-pata", "ata-generic";
|
compatible = "fsl,mpc8349emitx-pata", "ata-generic";
|
||||||
|
|
|
@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio)
|
||||||
return __gpio_cansleep(gpio);
|
return __gpio_cansleep(gpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Not implemented, yet.
|
|
||||||
*/
|
|
||||||
static inline int gpio_to_irq(unsigned int gpio)
|
static inline int gpio_to_irq(unsigned int gpio)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return __gpio_to_irq(gpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int irq_to_gpio(unsigned int irq)
|
static inline int irq_to_gpio(unsigned int irq)
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#define PMCCR1_NEXT_STATE 0x0C /* Next state for power management */
|
#define PMCCR1_NEXT_STATE 0x0C /* Next state for power management */
|
||||||
#define PMCCR1_NEXT_STATE_SHIFT 2
|
#define PMCCR1_NEXT_STATE_SHIFT 2
|
||||||
#define PMCCR1_CURR_STATE 0x03 /* Current state for power management*/
|
#define PMCCR1_CURR_STATE 0x03 /* Current state for power management*/
|
||||||
|
#define IMMR_SYSCR_OFFSET 0x100
|
||||||
#define IMMR_RCW_OFFSET 0x900
|
#define IMMR_RCW_OFFSET 0x900
|
||||||
#define RCW_PCI_HOST 0x80000000
|
#define RCW_PCI_HOST 0x80000000
|
||||||
|
|
||||||
|
@ -78,6 +79,22 @@ struct mpc83xx_clock {
|
||||||
u32 sccr;
|
u32 sccr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mpc83xx_syscr {
|
||||||
|
__be32 sgprl;
|
||||||
|
__be32 sgprh;
|
||||||
|
__be32 spridr;
|
||||||
|
__be32 :32;
|
||||||
|
__be32 spcr;
|
||||||
|
__be32 sicrl;
|
||||||
|
__be32 sicrh;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mpc83xx_saved {
|
||||||
|
u32 sicrl;
|
||||||
|
u32 sicrh;
|
||||||
|
u32 sccr;
|
||||||
|
};
|
||||||
|
|
||||||
struct pmc_type {
|
struct pmc_type {
|
||||||
int has_deep_sleep;
|
int has_deep_sleep;
|
||||||
};
|
};
|
||||||
|
@ -87,6 +104,8 @@ static int has_deep_sleep, deep_sleeping;
|
||||||
static int pmc_irq;
|
static int pmc_irq;
|
||||||
static struct mpc83xx_pmc __iomem *pmc_regs;
|
static struct mpc83xx_pmc __iomem *pmc_regs;
|
||||||
static struct mpc83xx_clock __iomem *clock_regs;
|
static struct mpc83xx_clock __iomem *clock_regs;
|
||||||
|
static struct mpc83xx_syscr __iomem *syscr_regs;
|
||||||
|
static struct mpc83xx_saved saved_regs;
|
||||||
static int is_pci_agent, wake_from_pci;
|
static int is_pci_agent, wake_from_pci;
|
||||||
static phys_addr_t immrbase;
|
static phys_addr_t immrbase;
|
||||||
static int pci_pm_state;
|
static int pci_pm_state;
|
||||||
|
@ -137,6 +156,20 @@ static irqreturn_t pmc_irq_handler(int irq, void *dev_id)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mpc83xx_suspend_restore_regs(void)
|
||||||
|
{
|
||||||
|
out_be32(&syscr_regs->sicrl, saved_regs.sicrl);
|
||||||
|
out_be32(&syscr_regs->sicrh, saved_regs.sicrh);
|
||||||
|
out_be32(&clock_regs->sccr, saved_regs.sccr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mpc83xx_suspend_save_regs(void)
|
||||||
|
{
|
||||||
|
saved_regs.sicrl = in_be32(&syscr_regs->sicrl);
|
||||||
|
saved_regs.sicrh = in_be32(&syscr_regs->sicrh);
|
||||||
|
saved_regs.sccr = in_be32(&clock_regs->sccr);
|
||||||
|
}
|
||||||
|
|
||||||
static int mpc83xx_suspend_enter(suspend_state_t state)
|
static int mpc83xx_suspend_enter(suspend_state_t state)
|
||||||
{
|
{
|
||||||
int ret = -EAGAIN;
|
int ret = -EAGAIN;
|
||||||
|
@ -166,6 +199,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (deep_sleeping) {
|
if (deep_sleeping) {
|
||||||
|
mpc83xx_suspend_save_regs();
|
||||||
|
|
||||||
out_be32(&pmc_regs->mask, PMCER_ALL);
|
out_be32(&pmc_regs->mask, PMCER_ALL);
|
||||||
|
|
||||||
out_be32(&pmc_regs->config1,
|
out_be32(&pmc_regs->config1,
|
||||||
|
@ -179,6 +214,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state)
|
||||||
in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF);
|
in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF);
|
||||||
|
|
||||||
out_be32(&pmc_regs->mask, PMCER_PMCI);
|
out_be32(&pmc_regs->mask, PMCER_PMCI);
|
||||||
|
|
||||||
|
mpc83xx_suspend_restore_regs();
|
||||||
} else {
|
} else {
|
||||||
out_be32(&pmc_regs->mask, PMCER_PMCI);
|
out_be32(&pmc_regs->mask, PMCER_PMCI);
|
||||||
|
|
||||||
|
@ -194,7 +231,7 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mpc83xx_suspend_finish(void)
|
static void mpc83xx_suspend_end(void)
|
||||||
{
|
{
|
||||||
deep_sleeping = 0;
|
deep_sleeping = 0;
|
||||||
}
|
}
|
||||||
|
@ -278,7 +315,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = {
|
||||||
.valid = mpc83xx_suspend_valid,
|
.valid = mpc83xx_suspend_valid,
|
||||||
.begin = mpc83xx_suspend_begin,
|
.begin = mpc83xx_suspend_begin,
|
||||||
.enter = mpc83xx_suspend_enter,
|
.enter = mpc83xx_suspend_enter,
|
||||||
.finish = mpc83xx_suspend_finish,
|
.end = mpc83xx_suspend_end,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pmc_probe(struct of_device *ofdev,
|
static int pmc_probe(struct of_device *ofdev,
|
||||||
|
@ -333,12 +370,23 @@ static int pmc_probe(struct of_device *ofdev,
|
||||||
goto out_pmc;
|
goto out_pmc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_deep_sleep) {
|
||||||
|
syscr_regs = ioremap(immrbase + IMMR_SYSCR_OFFSET,
|
||||||
|
sizeof(*syscr_regs));
|
||||||
|
if (!syscr_regs) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out_syscr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (is_pci_agent)
|
if (is_pci_agent)
|
||||||
mpc83xx_set_agent();
|
mpc83xx_set_agent();
|
||||||
|
|
||||||
suspend_set_ops(&mpc83xx_suspend_ops);
|
suspend_set_ops(&mpc83xx_suspend_ops);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
out_syscr:
|
||||||
|
iounmap(clock_regs);
|
||||||
out_pmc:
|
out_pmc:
|
||||||
iounmap(pmc_regs);
|
iounmap(pmc_regs);
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -143,13 +143,23 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type)
|
||||||
struct irq_desc *desc = irq_to_desc(virq);
|
struct irq_desc *desc = irq_to_desc(virq);
|
||||||
unsigned int vold, vnew, edibit;
|
unsigned int vold, vnew, edibit;
|
||||||
|
|
||||||
if (flow_type == IRQ_TYPE_NONE)
|
/* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
|
||||||
flow_type = IRQ_TYPE_LEVEL_LOW;
|
* IRQ_TYPE_EDGE_BOTH (default). All others are IRQ_TYPE_EDGE_FALLING
|
||||||
|
* or IRQ_TYPE_LEVEL_LOW (default)
|
||||||
|
*/
|
||||||
|
if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) {
|
||||||
|
if (flow_type == IRQ_TYPE_NONE)
|
||||||
|
flow_type = IRQ_TYPE_EDGE_BOTH;
|
||||||
|
|
||||||
if (flow_type & IRQ_TYPE_EDGE_RISING) {
|
if (flow_type != IRQ_TYPE_EDGE_BOTH &&
|
||||||
printk(KERN_ERR "CPM2 PIC: sense type 0x%x not supported\n",
|
flow_type != IRQ_TYPE_EDGE_FALLING)
|
||||||
flow_type);
|
goto err_sense;
|
||||||
return -EINVAL;
|
} else {
|
||||||
|
if (flow_type == IRQ_TYPE_NONE)
|
||||||
|
flow_type = IRQ_TYPE_LEVEL_LOW;
|
||||||
|
|
||||||
|
if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH))
|
||||||
|
goto err_sense;
|
||||||
}
|
}
|
||||||
|
|
||||||
desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
|
desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
|
||||||
|
@ -181,6 +191,10 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type)
|
||||||
if (vold != vnew)
|
if (vold != vnew)
|
||||||
out_be32(&cpm2_intctl->ic_siexr, vnew);
|
out_be32(&cpm2_intctl->ic_siexr, vnew);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_sense:
|
||||||
|
pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type);
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct irq_chip cpm2_pic = {
|
static struct irq_chip cpm2_pic = {
|
||||||
|
|
|
@ -464,8 +464,7 @@ static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus,
|
||||||
{
|
{
|
||||||
struct pci_controller *hose = pci_bus_to_host(bus);
|
struct pci_controller *hose = pci_bus_to_host(bus);
|
||||||
struct mpc83xx_pcie_priv *pcie = hose->dn->data;
|
struct mpc83xx_pcie_priv *pcie = hose->dn->data;
|
||||||
u8 bus_no = bus->number - hose->first_busno;
|
u32 dev_base = bus->number << 24 | devfn << 16;
|
||||||
u32 dev_base = bus_no << 24 | devfn << 16;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = mpc83xx_pcie_exclude_device(bus, devfn);
|
ret = mpc83xx_pcie_exclude_device(bus, devfn);
|
||||||
|
@ -515,12 +514,17 @@ static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||||
static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
|
static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||||
int offset, int len, u32 val)
|
int offset, int len, u32 val)
|
||||||
{
|
{
|
||||||
|
struct pci_controller *hose = pci_bus_to_host(bus);
|
||||||
void __iomem *cfg_addr;
|
void __iomem *cfg_addr;
|
||||||
|
|
||||||
cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
|
cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
|
||||||
if (!cfg_addr)
|
if (!cfg_addr)
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
|
/* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */
|
||||||
|
if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno)
|
||||||
|
val &= 0xffffff00;
|
||||||
|
|
||||||
switch (len) {
|
switch (len) {
|
||||||
case 1:
|
case 1:
|
||||||
out_8(cfg_addr, val);
|
out_8(cfg_addr, val);
|
||||||
|
|
|
@ -54,6 +54,22 @@ static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm)
|
||||||
mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT);
|
mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
|
||||||
|
* defined as output cannot be determined by reading GPDAT register,
|
||||||
|
* so we use shadow data register instead. The status of input pins
|
||||||
|
* is determined by reading GPDAT register.
|
||||||
|
*/
|
||||||
|
static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
|
||||||
|
struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
|
||||||
|
|
||||||
|
val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR);
|
||||||
|
|
||||||
|
return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio);
|
||||||
|
}
|
||||||
|
|
||||||
static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
|
static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
|
||||||
{
|
{
|
||||||
struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
|
struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
|
||||||
|
@ -136,7 +152,10 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
|
||||||
gc->ngpio = MPC8XXX_GPIO_PINS;
|
gc->ngpio = MPC8XXX_GPIO_PINS;
|
||||||
gc->direction_input = mpc8xxx_gpio_dir_in;
|
gc->direction_input = mpc8xxx_gpio_dir_in;
|
||||||
gc->direction_output = mpc8xxx_gpio_dir_out;
|
gc->direction_output = mpc8xxx_gpio_dir_out;
|
||||||
gc->get = mpc8xxx_gpio_get;
|
if (of_device_is_compatible(np, "fsl,mpc8572-gpio"))
|
||||||
|
gc->get = mpc8572_gpio_get;
|
||||||
|
else
|
||||||
|
gc->get = mpc8xxx_gpio_get;
|
||||||
gc->set = mpc8xxx_gpio_set;
|
gc->set = mpc8xxx_gpio_set;
|
||||||
|
|
||||||
ret = of_mm_gpiochip_add(np, mm_gc);
|
ret = of_mm_gpiochip_add(np, mm_gc);
|
||||||
|
|
Loading…
Reference in a new issue