diff options
Diffstat (limited to 'arch/powerpc/sysdev/qe_lib')
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/Kconfig | 12 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/gpio.c | 180 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe.c | 168 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe_ic.c | 104 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe_ic.h | 4 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe_io.c | 13 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/ucc.c | 10 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/ucc_fast.c | 5 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/ucc_slow.c | 5 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/usb.c | 3 |
10 files changed, 391 insertions, 113 deletions
diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig index 1ce546462be..3c251993bac 100644 --- a/arch/powerpc/sysdev/qe_lib/Kconfig +++ b/arch/powerpc/sysdev/qe_lib/Kconfig @@ -22,14 +22,6 @@ config UCC config QE_USB bool + default y if USB_FSL_QE help - QE USB Host Controller support - -config QE_GPIO - bool "QE GPIO support" - depends on QUICC_ENGINE - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB - help - Say Y here if you're going to use hardware that connects to the - QE GPIOs. + QE USB Controller support diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c index 8e5a0bc36d0..521e67a49dc 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/arch/powerpc/sysdev/qe_lib/gpio.c @@ -14,18 +14,27 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/spinlock.h> +#include <linux/err.h> #include <linux/io.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/gpio.h> +#include <linux/slab.h> +#include <linux/export.h> #include <asm/qe.h> struct qe_gpio_chip { struct of_mm_gpio_chip mm_gc; spinlock_t lock; + unsigned long pin_flags[QE_PIO_PINS]; +#define QE_PIN_REQUESTED 0 + /* shadowed data register to clear/set bits safely */ u32 cpdata; + + /* saved_regs used to restore dedicated functions */ + struct qe_pio_regs saved_regs; }; static inline struct qe_gpio_chip * @@ -40,6 +49,12 @@ static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc) struct qe_pio_regs __iomem *regs = mm_gc->regs; qe_gc->cpdata = in_be32(®s->cpdata); + qe_gc->saved_regs.cpdata = qe_gc->cpdata; + qe_gc->saved_regs.cpdir1 = in_be32(®s->cpdir1); + qe_gc->saved_regs.cpdir2 = in_be32(®s->cpdir2); + qe_gc->saved_regs.cppar1 = in_be32(®s->cppar1); + qe_gc->saved_regs.cppar2 = in_be32(®s->cppar2); + qe_gc->saved_regs.cpodr = in_be32(®s->cpodr); } static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio) @@ -92,17 +107,173 @@ static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc); unsigned long flags; + qe_gpio_set(gc, gpio, val); + spin_lock_irqsave(&qe_gc->lock, flags); __par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_OUT, 0, 0, 0); spin_unlock_irqrestore(&qe_gc->lock, flags); - qe_gpio_set(gc, gpio, val); - return 0; } +struct qe_pin { + /* + * The qe_gpio_chip name is unfortunate, we should change that to + * something like qe_pio_controller. Someday. + */ + struct qe_gpio_chip *controller; + int num; +}; + +/** + * qe_pin_request - Request a QE pin + * @np: device node to get a pin from + * @index: index of a pin in the device tree + * Context: non-atomic + * + * This function return qe_pin so that you could use it with the rest of + * the QE Pin Multiplexing API. + */ +struct qe_pin *qe_pin_request(struct device_node *np, int index) +{ + struct qe_pin *qe_pin; + struct gpio_chip *gc; + struct of_mm_gpio_chip *mm_gc; + struct qe_gpio_chip *qe_gc; + int err; + unsigned long flags; + + qe_pin = kzalloc(sizeof(*qe_pin), GFP_KERNEL); + if (!qe_pin) { + pr_debug("%s: can't allocate memory\n", __func__); + return ERR_PTR(-ENOMEM); + } + + err = of_get_gpio(np, index); + if (err < 0) + goto err0; + gc = gpio_to_chip(err); + if (WARN_ON(!gc)) + goto err0; + + if (!of_device_is_compatible(gc->of_node, "fsl,mpc8323-qe-pario-bank")) { + pr_debug("%s: tried to get a non-qe pin\n", __func__); + err = -EINVAL; + goto err0; + } + + mm_gc = to_of_mm_gpio_chip(gc); + qe_gc = to_qe_gpio_chip(mm_gc); + + spin_lock_irqsave(&qe_gc->lock, flags); + + err -= gc->base; + if (test_and_set_bit(QE_PIN_REQUESTED, &qe_gc->pin_flags[err]) == 0) { + qe_pin->controller = qe_gc; + qe_pin->num = err; + err = 0; + } else { + err = -EBUSY; + } + + spin_unlock_irqrestore(&qe_gc->lock, flags); + + if (!err) + return qe_pin; +err0: + kfree(qe_pin); + pr_debug("%s failed with status %d\n", __func__, err); + return ERR_PTR(err); +} +EXPORT_SYMBOL(qe_pin_request); + +/** + * qe_pin_free - Free a pin + * @qe_pin: pointer to the qe_pin structure + * Context: any + * + * This function frees the qe_pin structure and makes a pin available + * for further qe_pin_request() calls. + */ +void qe_pin_free(struct qe_pin *qe_pin) +{ + struct qe_gpio_chip *qe_gc = qe_pin->controller; + unsigned long flags; + const int pin = qe_pin->num; + + spin_lock_irqsave(&qe_gc->lock, flags); + test_and_clear_bit(QE_PIN_REQUESTED, &qe_gc->pin_flags[pin]); + spin_unlock_irqrestore(&qe_gc->lock, flags); + + kfree(qe_pin); +} +EXPORT_SYMBOL(qe_pin_free); + +/** + * qe_pin_set_dedicated - Revert a pin to a dedicated peripheral function mode + * @qe_pin: pointer to the qe_pin structure + * Context: any + * + * This function resets a pin to a dedicated peripheral function that + * has been set up by the firmware. + */ +void qe_pin_set_dedicated(struct qe_pin *qe_pin) +{ + struct qe_gpio_chip *qe_gc = qe_pin->controller; + struct qe_pio_regs __iomem *regs = qe_gc->mm_gc.regs; + struct qe_pio_regs *sregs = &qe_gc->saved_regs; + int pin = qe_pin->num; + u32 mask1 = 1 << (QE_PIO_PINS - (pin + 1)); + u32 mask2 = 0x3 << (QE_PIO_PINS - (pin % (QE_PIO_PINS / 2) + 1) * 2); + bool second_reg = pin > (QE_PIO_PINS / 2) - 1; + unsigned long flags; + + spin_lock_irqsave(&qe_gc->lock, flags); + + if (second_reg) { + clrsetbits_be32(®s->cpdir2, mask2, sregs->cpdir2 & mask2); + clrsetbits_be32(®s->cppar2, mask2, sregs->cppar2 & mask2); + } else { + clrsetbits_be32(®s->cpdir1, mask2, sregs->cpdir1 & mask2); + clrsetbits_be32(®s->cppar1, mask2, sregs->cppar1 & mask2); + } + + if (sregs->cpdata & mask1) + qe_gc->cpdata |= mask1; + else + qe_gc->cpdata &= ~mask1; + + out_be32(®s->cpdata, qe_gc->cpdata); + clrsetbits_be32(®s->cpodr, mask1, sregs->cpodr & mask1); + + spin_unlock_irqrestore(&qe_gc->lock, flags); +} +EXPORT_SYMBOL(qe_pin_set_dedicated); + +/** + * qe_pin_set_gpio - Set a pin to the GPIO mode + * @qe_pin: pointer to the qe_pin structure + * Context: any + * + * This function sets a pin to the GPIO mode. + */ +void qe_pin_set_gpio(struct qe_pin *qe_pin) +{ + struct qe_gpio_chip *qe_gc = qe_pin->controller; + struct qe_pio_regs __iomem *regs = qe_gc->mm_gc.regs; + unsigned long flags; + + spin_lock_irqsave(&qe_gc->lock, flags); + + /* Let's make it input by default, GPIO API is able to change that. */ + __par_io_config_pin(regs, qe_pin->num, QE_PIO_DIR_IN, 0, 0, 0); + + spin_unlock_irqrestore(&qe_gc->lock, flags); +} +EXPORT_SYMBOL(qe_pin_set_gpio); + static int __init qe_add_gpiochips(void) { struct device_node *np; @@ -111,7 +282,6 @@ static int __init qe_add_gpiochips(void) int ret; struct qe_gpio_chip *qe_gc; struct of_mm_gpio_chip *mm_gc; - struct of_gpio_chip *of_gc; struct gpio_chip *gc; qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL); @@ -123,11 +293,9 @@ static int __init qe_add_gpiochips(void) spin_lock_init(&qe_gc->lock); mm_gc = &qe_gc->mm_gc; - of_gc = &mm_gc->of_gc; - gc = &of_gc->gc; + gc = &mm_gc->gc; mm_gc->save_regs = qe_gpio_save_regs; - of_gc->gpio_cells = 2; gc->ngpio = QE_PIO_PINS; gc->direction_input = qe_gpio_dir_in; gc->direction_output = qe_gpio_dir_out; diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index b3b73ae57d6..238a07b97f2 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. + * Copyright (C) 2006-2010 Freescale Semiconductor, Inc. All rights reserved. * * Authors: Shlomi Gridish <gridish@freescale.com> * Li Yang <leoli@freescale.com> @@ -19,6 +19,7 @@ #include <linux/kernel.h> #include <linux/param.h> #include <linux/string.h> +#include <linux/spinlock.h> #include <linux/mm.h> #include <linux/interrupt.h> #include <linux/bootmem.h> @@ -26,6 +27,8 @@ #include <linux/delay.h> #include <linux/ioport.h> #include <linux/crc32.h> +#include <linux/mod_devicetable.h> +#include <linux/of_platform.h> #include <asm/irq.h> #include <asm/page.h> #include <asm/pgtable.h> @@ -38,6 +41,8 @@ static void qe_snums_init(void); static int qe_sdma_init(void); static DEFINE_SPINLOCK(qe_lock); +DEFINE_SPINLOCK(cmxgcr_lock); +EXPORT_SYMBOL(cmxgcr_lock); /* QE snum state */ enum qe_snum_state { @@ -58,6 +63,7 @@ struct qe_immap __iomem *qe_immr; EXPORT_SYMBOL(qe_immr); static struct qe_snum snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */ +static unsigned int qe_num_of_snum; static phys_addr_t qebase = -1; @@ -87,7 +93,7 @@ phys_addr_t get_qe_base(void) EXPORT_SYMBOL(get_qe_base); -void __init qe_reset(void) +void qe_reset(void) { if (qe_immr == NULL) qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE); @@ -108,6 +114,7 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input) { unsigned long flags; u8 mcn_shift = 0, dev_shift = 0; + u32 ret; spin_lock_irqsave(&qe_lock, flags); if (cmd == QE_RESET) { @@ -135,11 +142,13 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input) } /* wait for the QE_CR_FLG to clear */ - while(in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) - cpu_relax(); + ret = spin_event_timeout((in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) == 0, + 100, 0); + /* On timeout (e.g. failure), the expression will be false (ret == 0), + otherwise it will be true (ret == 1). */ spin_unlock_irqrestore(&qe_lock, flags); - return 0; + return ret == 1; } EXPORT_SYMBOL(qe_issue_cmd); @@ -207,7 +216,7 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier) /* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says that the BRG divisor must be even if you're not using divide-by-16 mode. */ - if (!div16 && (divisor & 1)) + if (!div16 && (divisor & 1) && (divisor > 3)) divisor++; tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | @@ -257,14 +266,36 @@ EXPORT_SYMBOL(qe_clock_source); static void qe_snums_init(void) { int i; - static const u8 snum_init[] = { + static const u8 snum_init_76[] = { + 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D, + 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89, + 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9, + 0xD8, 0xD9, 0xE8, 0xE9, 0x44, 0x45, 0x4C, 0x4D, + 0x54, 0x55, 0x5C, 0x5D, 0x64, 0x65, 0x6C, 0x6D, + 0x74, 0x75, 0x7C, 0x7D, 0x84, 0x85, 0x8C, 0x8D, + 0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD, + 0xB4, 0xB5, 0xBC, 0xBD, 0xC4, 0xC5, 0xCC, 0xCD, + 0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED, + 0xF4, 0xF5, 0xFC, 0xFD, + }; + static const u8 snum_init_46[] = { 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D, 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89, 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9, - 0xD8, 0xD9, 0xE8, 0xE9, + 0xD8, 0xD9, 0xE8, 0xE9, 0x08, 0x09, 0x18, 0x19, + 0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59, + 0x68, 0x69, 0x78, 0x79, 0x80, 0x81, }; + static const u8 *snum_init; + + qe_num_of_snum = qe_get_num_of_snums(); + + if (qe_num_of_snum == 76) + snum_init = snum_init_76; + else + snum_init = snum_init_46; - for (i = 0; i < QE_NUM_OF_SNUM; i++) { + for (i = 0; i < qe_num_of_snum; i++) { snums[i].num = snum_init[i]; snums[i].state = QE_SNUM_STATE_FREE; } @@ -277,7 +308,7 @@ int qe_get_snum(void) int i; spin_lock_irqsave(&qe_lock, flags); - for (i = 0; i < QE_NUM_OF_SNUM; i++) { + for (i = 0; i < qe_num_of_snum; i++) { if (snums[i].state == QE_SNUM_STATE_FREE) { snums[i].state = QE_SNUM_STATE_USED; snum = snums[i].num; @@ -294,7 +325,7 @@ void qe_put_snum(u8 snum) { int i; - for (i = 0; i < QE_NUM_OF_SNUM; i++) { + for (i = 0; i < qe_num_of_snum; i++) { if (snums[i].num == snum) { snums[i].state = QE_SNUM_STATE_FREE; break; @@ -306,16 +337,18 @@ EXPORT_SYMBOL(qe_put_snum); static int qe_sdma_init(void) { struct sdma __iomem *sdma = &qe_immr->sdma; - unsigned long sdma_buf_offset; + static unsigned long sdma_buf_offset = (unsigned long)-ENOMEM; if (!sdma) return -ENODEV; /* allocate 2 internal temporary buffers (512 bytes size each) for * the SDMA */ - sdma_buf_offset = qe_muram_alloc(512 * 2, 4096); - if (IS_ERR_VALUE(sdma_buf_offset)) - return -ENOMEM; + if (IS_ERR_VALUE(sdma_buf_offset)) { + sdma_buf_offset = qe_muram_alloc(512 * 2, 4096); + if (IS_ERR_VALUE(sdma_buf_offset)) + return -ENOMEM; + } out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK); out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK | @@ -325,7 +358,7 @@ static int qe_sdma_init(void) } /* The maximum number of RISCs we support */ -#define MAX_QE_RISC 2 +#define MAX_QE_RISC 4 /* Firmware information stored here for qe_get_firmware_info() */ static struct qe_firmware_info qe_firmware_info; @@ -362,12 +395,15 @@ static void qe_upload_microcode(const void *base, for (i = 0; i < be32_to_cpu(ucode->count); i++) out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i])); + + /* Set I-RAM Ready Register */ + out_be32(&qe_immr->iram.iready, be32_to_cpu(QE_IRAM_READY)); } /* * Upload a microcode to the I-RAM at a specific address. * - * See Documentation/powerpc/qe-firmware.txt for information on QE microcode + * See Documentation/powerpc/qe_firmware.txt for information on QE microcode * uploading. * * Currently, only version 1 is supported, so the 'version' field must be @@ -572,3 +608,101 @@ struct qe_firmware_info *qe_get_firmware_info(void) } EXPORT_SYMBOL(qe_get_firmware_info); +unsigned int qe_get_num_of_risc(void) +{ + struct device_node *qe; + int size; + unsigned int num_of_risc = 0; + const u32 *prop; + + qe = of_find_compatible_node(NULL, NULL, "fsl,qe"); + if (!qe) { + /* Older devices trees did not have an "fsl,qe" + * compatible property, so we need to look for + * the QE node by name. + */ + qe = of_find_node_by_type(NULL, "qe"); + if (!qe) + return num_of_risc; + } + + prop = of_get_property(qe, "fsl,qe-num-riscs", &size); + if (prop && size == sizeof(*prop)) + num_of_risc = *prop; + + of_node_put(qe); + + return num_of_risc; +} +EXPORT_SYMBOL(qe_get_num_of_risc); + +unsigned int qe_get_num_of_snums(void) +{ + struct device_node *qe; + int size; + unsigned int num_of_snums; + const u32 *prop; + + num_of_snums = 28; /* The default number of snum for threads is 28 */ + qe = of_find_compatible_node(NULL, NULL, "fsl,qe"); + if (!qe) { + /* Older devices trees did not have an "fsl,qe" + * compatible property, so we need to look for + * the QE node by name. + */ + qe = of_find_node_by_type(NULL, "qe"); + if (!qe) + return num_of_snums; + } + + prop = of_get_property(qe, "fsl,qe-num-snums", &size); + if (prop && size == sizeof(*prop)) { + num_of_snums = *prop; + if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) { + /* No QE ever has fewer than 28 SNUMs */ + pr_err("QE: number of snum is invalid\n"); + of_node_put(qe); + return -EINVAL; + } + } + + of_node_put(qe); + + return num_of_snums; +} +EXPORT_SYMBOL(qe_get_num_of_snums); + +#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) +static int qe_resume(struct platform_device *ofdev) +{ + if (!qe_alive_during_sleep()) + qe_reset(); + return 0; +} + +static int qe_probe(struct platform_device *ofdev) +{ + return 0; +} + +static const struct of_device_id qe_ids[] = { + { .compatible = "fsl,qe", }, + { }, +}; + +static struct platform_driver qe_driver = { + .driver = { + .name = "fsl-qe", + .owner = THIS_MODULE, + .of_match_table = qe_ids, + }, + .probe = qe_probe, + .resume = qe_resume, +}; + +static int __init qe_drv_init(void) +{ + return platform_driver_register(&qe_driver); +} +device_initcall(qe_drv_init); +#endif /* defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) */ diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c index 63cdf9887f3..b2b87c30e26 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c @@ -1,7 +1,7 @@ /* * arch/powerpc/sysdev/qe_lib/qe_ic.c * - * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. + * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. * * Author: Li Yang <leoli@freescale.com> * Based on code from Shlomi Gridish <gridish@freescale.com> @@ -22,7 +22,6 @@ #include <linux/stddef.h> #include <linux/sched.h> #include <linux/signal.h> -#include <linux/sysdev.h> #include <linux/device.h> #include <linux/bootmem.h> #include <linux/spinlock.h> @@ -33,7 +32,7 @@ #include "qe_ic.h" -static DEFINE_SPINLOCK(qe_ic_lock); +static DEFINE_RAW_SPINLOCK(qe_ic_lock); static struct qe_ic_info qe_ic_info[] = { [1] = { @@ -189,35 +188,38 @@ static inline void qe_ic_write(volatile __be32 __iomem * base, unsigned int reg static inline struct qe_ic *qe_ic_from_irq(unsigned int virq) { - return irq_desc[virq].chip_data; + return irq_get_chip_data(virq); } -#define virq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq) +static inline struct qe_ic *qe_ic_from_irq_data(struct irq_data *d) +{ + return irq_data_get_irq_chip_data(d); +} -static void qe_ic_unmask_irq(unsigned int virq) +static void qe_ic_unmask_irq(struct irq_data *d) { - struct qe_ic *qe_ic = qe_ic_from_irq(virq); - unsigned int src = virq_to_hw(virq); + struct qe_ic *qe_ic = qe_ic_from_irq_data(d); + unsigned int src = irqd_to_hwirq(d); unsigned long flags; u32 temp; - spin_lock_irqsave(&qe_ic_lock, flags); + raw_spin_lock_irqsave(&qe_ic_lock, flags); temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg); qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg, temp | qe_ic_info[src].mask); - spin_unlock_irqrestore(&qe_ic_lock, flags); + raw_spin_unlock_irqrestore(&qe_ic_lock, flags); } -static void qe_ic_mask_irq(unsigned int virq) +static void qe_ic_mask_irq(struct irq_data *d) { - struct qe_ic *qe_ic = qe_ic_from_irq(virq); - unsigned int src = virq_to_hw(virq); + struct qe_ic *qe_ic = qe_ic_from_irq_data(d); + unsigned int src = irqd_to_hwirq(d); unsigned long flags; u32 temp; - spin_lock_irqsave(&qe_ic_lock, flags); + raw_spin_lock_irqsave(&qe_ic_lock, flags); temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg); qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg, @@ -233,60 +235,47 @@ static void qe_ic_mask_irq(unsigned int virq) */ mb(); - spin_unlock_irqrestore(&qe_ic_lock, flags); + raw_spin_unlock_irqrestore(&qe_ic_lock, flags); } static struct irq_chip qe_ic_irq_chip = { - .typename = " QEIC ", - .unmask = qe_ic_unmask_irq, - .mask = qe_ic_mask_irq, - .mask_ack = qe_ic_mask_irq, + .name = "QEIC", + .irq_unmask = qe_ic_unmask_irq, + .irq_mask = qe_ic_mask_irq, + .irq_mask_ack = qe_ic_mask_irq, }; -static int qe_ic_host_match(struct irq_host *h, struct device_node *node) +static int qe_ic_host_match(struct irq_domain *h, struct device_node *node) { /* Exact match, unless qe_ic node is NULL */ return h->of_node == NULL || h->of_node == node; } -static int qe_ic_host_map(struct irq_host *h, unsigned int virq, +static int qe_ic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct qe_ic *qe_ic = h->host_data; struct irq_chip *chip; if (qe_ic_info[hw].mask == 0) { - printk(KERN_ERR "Can't map reserved IRQ \n"); + printk(KERN_ERR "Can't map reserved IRQ\n"); return -EINVAL; } /* Default chip */ chip = &qe_ic->hc_irq; - set_irq_chip_data(virq, qe_ic); - get_irq_desc(virq)->status |= IRQ_LEVEL; + irq_set_chip_data(virq, qe_ic); + irq_set_status_flags(virq, IRQ_LEVEL); - set_irq_chip_and_handler(virq, chip, handle_level_irq); + irq_set_chip_and_handler(virq, chip, handle_level_irq); return 0; } -static int qe_ic_host_xlate(struct irq_host *h, struct device_node *ct, - u32 * intspec, unsigned int intsize, - irq_hw_number_t * out_hwirq, - unsigned int *out_flags) -{ - *out_hwirq = intspec[0]; - if (intsize > 1) - *out_flags = intspec[1]; - else - *out_flags = IRQ_TYPE_NONE; - return 0; -} - -static struct irq_host_ops qe_ic_host_ops = { +static struct irq_domain_ops qe_ic_host_ops = { .match = qe_ic_host_match, .map = qe_ic_host_map, - .xlate = qe_ic_host_xlate, + .xlate = irq_domain_xlate_onetwocell, }; /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ @@ -333,20 +322,19 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, if (ret) return; - qe_ic = alloc_bootmem(sizeof(struct qe_ic)); + qe_ic = kzalloc(sizeof(*qe_ic), GFP_KERNEL); if (qe_ic == NULL) return; - memset(qe_ic, 0, sizeof(struct qe_ic)); - - qe_ic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, - NR_QE_IC_INTS, &qe_ic_host_ops, 0); - if (qe_ic->irqhost == NULL) + qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS, + &qe_ic_host_ops, qe_ic); + if (qe_ic->irqhost == NULL) { + kfree(qe_ic); return; + } - qe_ic->regs = ioremap(res.start, res.end - res.start + 1); + qe_ic->regs = ioremap(res.start, resource_size(&res)); - qe_ic->irqhost->host_data = qe_ic; qe_ic->hc_irq = qe_ic_irq_chip; qe_ic->virq_high = irq_of_parse_and_map(node, 0); @@ -354,6 +342,7 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, if (qe_ic->virq_low == NO_IRQ) { printk(KERN_ERR "Failed to map QE_IC low IRQ\n"); + kfree(qe_ic); return; } @@ -380,13 +369,13 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, qe_ic_write(qe_ic->regs, QEIC_CICR, temp); - set_irq_data(qe_ic->virq_low, qe_ic); - set_irq_chained_handler(qe_ic->virq_low, low_handler); + irq_set_handler_data(qe_ic->virq_low, qe_ic); + irq_set_chained_handler(qe_ic->virq_low, low_handler); if (qe_ic->virq_high != NO_IRQ && qe_ic->virq_high != qe_ic->virq_low) { - set_irq_data(qe_ic->virq_high, qe_ic); - set_irq_chained_handler(qe_ic->virq_high, high_handler); + irq_set_handler_data(qe_ic->virq_high, qe_ic); + irq_set_chained_handler(qe_ic->virq_high, high_handler); } } @@ -480,13 +469,14 @@ int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high) return 0; } -static struct sysdev_class qe_ic_sysclass = { +static struct bus_type qe_ic_subsys = { .name = "qe_ic", + .dev_name = "qe_ic", }; -static struct sys_device device_qe_ic = { +static struct device device_qe_ic = { .id = 0, - .cls = &qe_ic_sysclass, + .bus = &qe_ic_subsys, }; static int __init init_qe_ic_sysfs(void) @@ -495,12 +485,12 @@ static int __init init_qe_ic_sysfs(void) printk(KERN_DEBUG "Registering qe_ic with sysfs...\n"); - rc = sysdev_class_register(&qe_ic_sysclass); + rc = subsys_system_register(&qe_ic_subsys, NULL); if (rc) { printk(KERN_ERR "Failed registering qe_ic sys class\n"); return -ENODEV; } - rc = sysdev_register(&device_qe_ic); + rc = device_register(&device_qe_ic); if (rc) { printk(KERN_ERR "Failed registering qe_ic sys device\n"); return -ENODEV; diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.h b/arch/powerpc/sysdev/qe_lib/qe_ic.h index c1361d005a8..efef7ab9b75 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.h +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.h @@ -3,7 +3,7 @@ * * QUICC ENGINE Interrupt Controller Header * - * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. + * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. * * Author: Li Yang <leoli@freescale.com> * Based on code from Shlomi Gridish <gridish@freescale.com> @@ -79,7 +79,7 @@ struct qe_ic { volatile u32 __iomem *regs; /* The remapper for this QEIC */ - struct irq_host *irqhost; + struct irq_domain *irqhost; /* The "linux" controller struct */ struct irq_chip hc_irq; diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/arch/powerpc/sysdev/qe_lib/qe_io.c index 7c87460179e..d09994164da 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_io.c +++ b/arch/powerpc/sysdev/qe_lib/qe_io.c @@ -3,7 +3,7 @@ * * QE Parallel I/O ports configuration routines * - * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. + * Copyright 2006 Freescale Semiconductor, Inc. All rights reserved. * * Author: Li Yang <LeoLi@freescale.com> * Based on code from Shlomi Gridish <gridish@freescale.com> @@ -16,7 +16,6 @@ #include <linux/stddef.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/errno.h> #include <linux/module.h> #include <linux/ioport.h> @@ -41,7 +40,7 @@ int par_io_init(struct device_node *np) ret = of_address_to_resource(np, 0, &res); if (ret) return ret; - par_io = ioremap(res.start, res.end - res.start + 1); + par_io = ioremap(res.start, resource_size(&res)); num_ports = of_get_property(np, "num-ports", NULL); if (num_ports) @@ -157,13 +156,13 @@ int par_io_of_config(struct device_node *np) const unsigned int *pio_map; if (par_io == NULL) { - printk(KERN_ERR "par_io not initialized \n"); + printk(KERN_ERR "par_io not initialized\n"); return -1; } ph = of_get_property(np, "pio-handle", NULL); if (ph == NULL) { - printk(KERN_ERR "pio-handle not available \n"); + printk(KERN_ERR "pio-handle not available\n"); return -1; } @@ -171,12 +170,12 @@ int par_io_of_config(struct device_node *np) pio_map = of_get_property(pio, "pio-map", &pio_map_len); if (pio_map == NULL) { - printk(KERN_ERR "pio-map is not set! \n"); + printk(KERN_ERR "pio-map is not set!\n"); return -1; } pio_map_len /= sizeof(unsigned int); if ((pio_map_len % 6) != 0) { - printk(KERN_ERR "pio-map format wrong! \n"); + printk(KERN_ERR "pio-map format wrong!\n"); return -1; } diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c index 1d78071aad7..621575b7e84 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc.c +++ b/arch/powerpc/sysdev/qe_lib/ucc.c @@ -3,7 +3,7 @@ * * QE UCC API Set - UCC specific routines implementations. * - * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. + * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. * * Authors: Shlomi Gridish <gridish@freescale.com> * Li Yang <leoli@freescale.com> @@ -14,11 +14,10 @@ * option) any later version. */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/errno.h> -#include <linux/slab.h> #include <linux/stddef.h> -#include <linux/module.h> +#include <linux/spinlock.h> +#include <linux/export.h> #include <asm/irq.h> #include <asm/io.h> @@ -26,9 +25,6 @@ #include <asm/qe.h> #include <asm/ucc.h> -DEFINE_SPINLOCK(cmxgcr_lock); -EXPORT_SYMBOL(cmxgcr_lock); - int ucc_set_qe_mux_mii_mng(unsigned int ucc_num) { unsigned long flags; diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c index 25fbbfaa837..65aaf15032a 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c +++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. + * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. * * Authors: Shlomi Gridish <gridish@freescale.com> * Li Yang <leoli@freescale.com> @@ -13,13 +13,12 @@ * option) any later version. */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/errno.h> #include <linux/slab.h> #include <linux/stddef.h> #include <linux/interrupt.h> #include <linux/err.h> -#include <linux/module.h> +#include <linux/export.h> #include <asm/io.h> #include <asm/immap_qe.h> diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c index e1d6a134015..befaf1123f7 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c +++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. + * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. * * Authors: Shlomi Gridish <gridish@freescale.com> * Li Yang <leoli@freescale.com> @@ -13,13 +13,12 @@ * option) any later version. */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/errno.h> #include <linux/slab.h> #include <linux/stddef.h> #include <linux/interrupt.h> #include <linux/err.h> -#include <linux/module.h> +#include <linux/export.h> #include <asm/io.h> #include <asm/immap_qe.h> diff --git a/arch/powerpc/sysdev/qe_lib/usb.c b/arch/powerpc/sysdev/qe_lib/usb.c index 8105462078e..27f23bd15eb 100644 --- a/arch/powerpc/sysdev/qe_lib/usb.c +++ b/arch/powerpc/sysdev/qe_lib/usb.c @@ -1,7 +1,7 @@ /* * QE USB routines * - * Copyright (c) Freescale Semicondutor, Inc. 2006. + * Copyright 2006 Freescale Semiconductor, Inc. * Shlomi Gridish <gridish@freescale.com> * Jerry Huang <Chang-Ming.Huang@freescale.com> * Copyright (c) MontaVista Software, Inc. 2008. @@ -15,6 +15,7 @@ #include <linux/kernel.h> #include <linux/errno.h> +#include <linux/export.h> #include <linux/io.h> #include <asm/immap_qe.h> #include <asm/qe.h> |
