diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-15 12:32:52 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-15 12:32:52 -0400 |
| commit | 0fa213310cd8fa7a51071cdcf130e26fa56e9549 (patch) | |
| tree | 2a7e5cc33c8938ec82604a99c3797a3132fd91ec /drivers | |
| parent | d3bf80bff13597004b5724ee4549cd68eb0badf0 (diff) | |
| parent | bc47ab0241c7c86da4f5e5f82fbca7d45387c18d (diff) | |
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (103 commits)
powerpc: Fix bug in move of altivec code to vector.S
powerpc: Add support for swiotlb on 32-bit
powerpc/spufs: Remove unused error path
powerpc: Fix warning when printing a resource_size_t
powerpc/xmon: Remove unused variable in xmon.c
powerpc/pseries: Fix warnings when printing resource_size_t
powerpc: Shield code specific to 64-bit server processors
powerpc: Separate PACA fields for server CPUs
powerpc: Split exception handling out of head_64.S
powerpc: Introduce CONFIG_PPC_BOOK3S
powerpc: Move VMX and VSX asm code to vector.S
powerpc: Set init_bootmem_done on NUMA platforms as well
powerpc/mm: Fix a AB->BA deadlock scenario with nohash MMU context lock
powerpc/mm: Fix some SMP issues with MMU context handling
powerpc: Add PTRACE_SINGLEBLOCK support
fbdev: Add PLB support and cleanup DCR in xilinxfb driver.
powerpc/virtex: Add ml510 reference design device tree
powerpc/virtex: Add Xilinx ML510 reference design support
powerpc/virtex: refactor intc driver and add support for i8259 cascading
powerpc/virtex: Add support for Xilinx PCI host bridge
...
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/char/viotape.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-ibm_iic.c | 6 | ||||
| -rw-r--r-- | drivers/macintosh/therm_adt746x.c | 4 | ||||
| -rw-r--r-- | drivers/net/ucc_geth.c | 24 | ||||
| -rw-r--r-- | drivers/net/ucc_geth.h | 4 | ||||
| -rw-r--r-- | drivers/of/base.c | 1 | ||||
| -rw-r--r-- | drivers/pci/Makefile | 1 | ||||
| -rw-r--r-- | drivers/rapidio/rio-scan.c | 6 | ||||
| -rw-r--r-- | drivers/video/xilinxfb.c | 290 |
9 files changed, 184 insertions, 154 deletions
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index ffc9254f7e02..042c8149a6d1 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
| @@ -867,7 +867,7 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
| 867 | int j; | 867 | int j; |
| 868 | struct device_node *node = vdev->dev.archdata.of_node; | 868 | struct device_node *node = vdev->dev.archdata.of_node; |
| 869 | 869 | ||
| 870 | if (i > VIOTAPE_MAX_TAPE) | 870 | if (i >= VIOTAPE_MAX_TAPE) |
| 871 | return -ENODEV; | 871 | return -ENODEV; |
| 872 | if (!node) | 872 | if (!node) |
| 873 | return -ENODEV; | 873 | return -ENODEV; |
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 8b92a4666e02..e4476743f203 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c | |||
| @@ -756,12 +756,12 @@ static int __devinit iic_probe(struct of_device *ofdev, | |||
| 756 | goto error_cleanup; | 756 | goto error_cleanup; |
| 757 | } | 757 | } |
| 758 | 758 | ||
| 759 | /* Now register all the child nodes */ | ||
| 760 | of_register_i2c_devices(adap, np); | ||
| 761 | |||
| 762 | dev_info(&ofdev->dev, "using %s mode\n", | 759 | dev_info(&ofdev->dev, "using %s mode\n", |
| 763 | dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); | 760 | dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); |
| 764 | 761 | ||
| 762 | /* Now register all the child nodes */ | ||
| 763 | of_register_i2c_devices(adap, np); | ||
| 764 | |||
| 765 | return 0; | 765 | return 0; |
| 766 | 766 | ||
| 767 | error_cleanup: | 767 | error_cleanup: |
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index c0621d50c8a0..0ddf9044948a 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #define CONFIG_REG 0x40 | 37 | #define CONFIG_REG 0x40 |
| 38 | #define MANUAL_MASK 0xe0 | 38 | #define MANUAL_MASK 0xe0 |
| 39 | #define AUTO_MASK 0x20 | 39 | #define AUTO_MASK 0x20 |
| 40 | #define INVERT_MASK 0x10 | ||
| 40 | 41 | ||
| 41 | static u8 TEMP_REG[3] = {0x26, 0x25, 0x27}; /* local, sensor1, sensor2 */ | 42 | static u8 TEMP_REG[3] = {0x26, 0x25, 0x27}; /* local, sensor1, sensor2 */ |
| 42 | static u8 LIMIT_REG[3] = {0x6b, 0x6a, 0x6c}; /* local, sensor1, sensor2 */ | 43 | static u8 LIMIT_REG[3] = {0x6b, 0x6a, 0x6c}; /* local, sensor1, sensor2 */ |
| @@ -229,7 +230,8 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan) | |||
| 229 | 230 | ||
| 230 | if (speed >= 0) { | 231 | if (speed >= 0) { |
| 231 | manual = read_reg(th, MANUAL_MODE[fan]); | 232 | manual = read_reg(th, MANUAL_MODE[fan]); |
| 232 | write_reg(th, MANUAL_MODE[fan], manual|MANUAL_MASK); | 233 | write_reg(th, MANUAL_MODE[fan], |
| 234 | (manual|MANUAL_MASK) & (~INVERT_MASK)); | ||
| 233 | write_reg(th, FAN_SPD_SET[fan], speed); | 235 | write_reg(th, FAN_SPD_SET[fan], speed); |
| 234 | } else { | 236 | } else { |
| 235 | /* back to automatic */ | 237 | /* back to automatic */ |
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 44f8392da117..9dd16c9b1a10 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
| @@ -270,7 +270,7 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth, | |||
| 270 | u8 num_entries, | 270 | u8 num_entries, |
| 271 | u32 thread_size, | 271 | u32 thread_size, |
| 272 | u32 thread_alignment, | 272 | u32 thread_alignment, |
| 273 | enum qe_risc_allocation risc, | 273 | unsigned int risc, |
| 274 | int skip_page_for_first_entry) | 274 | int skip_page_for_first_entry) |
| 275 | { | 275 | { |
| 276 | u32 init_enet_offset; | 276 | u32 init_enet_offset; |
| @@ -307,7 +307,7 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth, | |||
| 307 | static int return_init_enet_entries(struct ucc_geth_private *ugeth, | 307 | static int return_init_enet_entries(struct ucc_geth_private *ugeth, |
| 308 | u32 *p_start, | 308 | u32 *p_start, |
| 309 | u8 num_entries, | 309 | u8 num_entries, |
| 310 | enum qe_risc_allocation risc, | 310 | unsigned int risc, |
| 311 | int skip_page_for_first_entry) | 311 | int skip_page_for_first_entry) |
| 312 | { | 312 | { |
| 313 | u32 init_enet_offset; | 313 | u32 init_enet_offset; |
| @@ -342,7 +342,7 @@ static int dump_init_enet_entries(struct ucc_geth_private *ugeth, | |||
| 342 | u32 __iomem *p_start, | 342 | u32 __iomem *p_start, |
| 343 | u8 num_entries, | 343 | u8 num_entries, |
| 344 | u32 thread_size, | 344 | u32 thread_size, |
| 345 | enum qe_risc_allocation risc, | 345 | unsigned int risc, |
| 346 | int skip_page_for_first_entry) | 346 | int skip_page_for_first_entry) |
| 347 | { | 347 | { |
| 348 | u32 init_enet_offset; | 348 | u32 init_enet_offset; |
| @@ -2135,6 +2135,14 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) | |||
| 2135 | return -ENOMEM; | 2135 | return -ENOMEM; |
| 2136 | } | 2136 | } |
| 2137 | 2137 | ||
| 2138 | /* read the number of risc engines, update the riscTx and riscRx | ||
| 2139 | * if there are 4 riscs in QE | ||
| 2140 | */ | ||
| 2141 | if (qe_get_num_of_risc() == 4) { | ||
| 2142 | ug_info->riscTx = QE_RISC_ALLOCATION_FOUR_RISCS; | ||
| 2143 | ug_info->riscRx = QE_RISC_ALLOCATION_FOUR_RISCS; | ||
| 2144 | } | ||
| 2145 | |||
| 2138 | ugeth->ug_regs = ioremap(uf_info->regs, sizeof(*ugeth->ug_regs)); | 2146 | ugeth->ug_regs = ioremap(uf_info->regs, sizeof(*ugeth->ug_regs)); |
| 2139 | if (!ugeth->ug_regs) { | 2147 | if (!ugeth->ug_regs) { |
| 2140 | if (netif_msg_probe(ugeth)) | 2148 | if (netif_msg_probe(ugeth)) |
| @@ -3702,7 +3710,15 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
| 3702 | ug_info->uf_info.utfet = UCC_GETH_UTFET_GIGA_INIT; | 3710 | ug_info->uf_info.utfet = UCC_GETH_UTFET_GIGA_INIT; |
| 3703 | ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT; | 3711 | ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT; |
| 3704 | ug_info->numThreadsTx = UCC_GETH_NUM_OF_THREADS_4; | 3712 | ug_info->numThreadsTx = UCC_GETH_NUM_OF_THREADS_4; |
| 3705 | ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4; | 3713 | |
| 3714 | /* If QE's snum number is 46 which means we need to support | ||
| 3715 | * 4 UECs at 1000Base-T simultaneously, we need to allocate | ||
| 3716 | * more Threads to Rx. | ||
| 3717 | */ | ||
| 3718 | if (qe_get_num_of_snums() == 46) | ||
| 3719 | ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_6; | ||
| 3720 | else | ||
| 3721 | ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4; | ||
| 3706 | } | 3722 | } |
| 3707 | 3723 | ||
| 3708 | if (netif_msg_probe(&debug)) | 3724 | if (netif_msg_probe(&debug)) |
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index 2f8ee7c87efe..46bb1d233597 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h | |||
| @@ -1120,8 +1120,8 @@ struct ucc_geth_info { | |||
| 1120 | enum ucc_geth_maccfg2_pad_and_crc_mode padAndCrc; | 1120 | enum ucc_geth_maccfg2_pad_and_crc_mode padAndCrc; |
| 1121 | enum ucc_geth_num_of_threads numThreadsTx; | 1121 | enum ucc_geth_num_of_threads numThreadsTx; |
| 1122 | enum ucc_geth_num_of_threads numThreadsRx; | 1122 | enum ucc_geth_num_of_threads numThreadsRx; |
| 1123 | enum qe_risc_allocation riscTx; | 1123 | unsigned int riscTx; |
| 1124 | enum qe_risc_allocation riscRx; | 1124 | unsigned int riscRx; |
| 1125 | }; | 1125 | }; |
| 1126 | 1126 | ||
| 1127 | /* structure representing UCC GETH */ | 1127 | /* structure representing UCC GETH */ |
diff --git a/drivers/of/base.c b/drivers/of/base.c index 41c5dfd85358..391f91c0bf55 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
| @@ -447,6 +447,7 @@ struct of_modalias_table { | |||
| 447 | static struct of_modalias_table of_modalias_table[] = { | 447 | static struct of_modalias_table of_modalias_table[] = { |
| 448 | { "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" }, | 448 | { "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" }, |
| 449 | { "mmc-spi-slot", "mmc_spi" }, | 449 | { "mmc-spi-slot", "mmc_spi" }, |
| 450 | { "stm,m25p40", "m25p80" }, | ||
| 450 | }; | 451 | }; |
| 451 | 452 | ||
| 452 | /** | 453 | /** |
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index ba6af162fd39..b77ae6794275 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
| @@ -39,7 +39,6 @@ obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o | |||
| 39 | obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o | 39 | obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o |
| 40 | obj-$(CONFIG_PARISC) += setup-bus.o | 40 | obj-$(CONFIG_PARISC) += setup-bus.o |
| 41 | obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o | 41 | obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o |
| 42 | obj-$(CONFIG_PPC32) += setup-irq.o | ||
| 43 | obj-$(CONFIG_PPC) += setup-bus.o | 42 | obj-$(CONFIG_PPC) += setup-bus.o |
| 44 | obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o | 43 | obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o |
| 45 | obj-$(CONFIG_X86_VISWS) += setup-irq.o | 44 | obj-$(CONFIG_X86_VISWS) += setup-irq.o |
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 74d0bfa3f310..3b78540288c7 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c | |||
| @@ -290,7 +290,7 @@ static void __devinit rio_add_device(struct rio_dev *rdev) | |||
| 290 | * to a RIO device on success or NULL on failure. | 290 | * to a RIO device on success or NULL on failure. |
| 291 | * | 291 | * |
| 292 | */ | 292 | */ |
| 293 | static struct rio_dev *rio_setup_device(struct rio_net *net, | 293 | static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, |
| 294 | struct rio_mport *port, u16 destid, | 294 | struct rio_mport *port, u16 destid, |
| 295 | u8 hopcount, int do_enum) | 295 | u8 hopcount, int do_enum) |
| 296 | { | 296 | { |
| @@ -559,7 +559,7 @@ static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port) | |||
| 559 | * Recursively enumerates a RIO network. Transactions are sent via the | 559 | * Recursively enumerates a RIO network. Transactions are sent via the |
| 560 | * master port passed in @port. | 560 | * master port passed in @port. |
| 561 | */ | 561 | */ |
| 562 | static int rio_enum_peer(struct rio_net *net, struct rio_mport *port, | 562 | static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, |
| 563 | u8 hopcount) | 563 | u8 hopcount) |
| 564 | { | 564 | { |
| 565 | int port_num; | 565 | int port_num; |
| @@ -718,7 +718,7 @@ static int rio_enum_complete(struct rio_mport *port) | |||
| 718 | * Recursively discovers a RIO network. Transactions are sent via the | 718 | * Recursively discovers a RIO network. Transactions are sent via the |
| 719 | * master port passed in @port. | 719 | * master port passed in @port. |
| 720 | */ | 720 | */ |
| 721 | static int | 721 | static int __devinit |
| 722 | rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, | 722 | rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, |
| 723 | u8 hopcount) | 723 | u8 hopcount) |
| 724 | { | 724 | { |
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 40a3a2afbfe7..7a868bd16e0e 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c | |||
| @@ -1,13 +1,12 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * xilinxfb.c | 2 | * Xilinx TFT frame buffer driver |
| 3 | * | ||
| 4 | * Xilinx TFT LCD frame buffer driver | ||
| 5 | * | 3 | * |
| 6 | * Author: MontaVista Software, Inc. | 4 | * Author: MontaVista Software, Inc. |
| 7 | * source@mvista.com | 5 | * source@mvista.com |
| 8 | * | 6 | * |
| 9 | * 2002-2007 (c) MontaVista Software, Inc. | 7 | * 2002-2007 (c) MontaVista Software, Inc. |
| 10 | * 2007 (c) Secret Lab Technologies, Ltd. | 8 | * 2007 (c) Secret Lab Technologies, Ltd. |
| 9 | * 2009 (c) Xilinx Inc. | ||
| 11 | * | 10 | * |
| 12 | * This file is licensed under the terms of the GNU General Public License | 11 | * This file is licensed under the terms of the GNU General Public License |
| 13 | * version 2. This program is licensed "as is" without any warranty of any | 12 | * version 2. This program is licensed "as is" without any warranty of any |
| @@ -24,33 +23,38 @@ | |||
| 24 | #include <linux/device.h> | 23 | #include <linux/device.h> |
| 25 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 26 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
| 26 | #include <linux/version.h> | ||
| 27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
| 28 | #include <linux/string.h> | 28 | #include <linux/string.h> |
| 29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
| 30 | #include <linux/fb.h> | 30 | #include <linux/fb.h> |
| 31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
| 32 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
| 33 | #include <linux/platform_device.h> | ||
| 34 | #if defined(CONFIG_OF) | ||
| 35 | #include <linux/of_device.h> | 33 | #include <linux/of_device.h> |
| 36 | #include <linux/of_platform.h> | 34 | #include <linux/of_platform.h> |
| 37 | #endif | 35 | #include <linux/io.h> |
| 38 | #include <asm/io.h> | ||
| 39 | #include <linux/xilinxfb.h> | 36 | #include <linux/xilinxfb.h> |
| 37 | #include <asm/dcr.h> | ||
| 40 | 38 | ||
| 41 | #define DRIVER_NAME "xilinxfb" | 39 | #define DRIVER_NAME "xilinxfb" |
| 42 | #define DRIVER_DESCRIPTION "Xilinx TFT LCD frame buffer driver" | 40 | |
| 43 | 41 | ||
| 44 | /* | 42 | /* |
| 45 | * Xilinx calls it "PLB TFT LCD Controller" though it can also be used for | 43 | * Xilinx calls it "PLB TFT LCD Controller" though it can also be used for |
| 46 | * the VGA port on the Xilinx ML40x board. This is a hardware display controller | 44 | * the VGA port on the Xilinx ML40x board. This is a hardware display |
| 47 | * for a 640x480 resolution TFT or VGA screen. | 45 | * controller for a 640x480 resolution TFT or VGA screen. |
| 48 | * | 46 | * |
| 49 | * The interface to the framebuffer is nice and simple. There are two | 47 | * The interface to the framebuffer is nice and simple. There are two |
| 50 | * control registers. The first tells the LCD interface where in memory | 48 | * control registers. The first tells the LCD interface where in memory |
| 51 | * the frame buffer is (only the 11 most significant bits are used, so | 49 | * the frame buffer is (only the 11 most significant bits are used, so |
| 52 | * don't start thinking about scrolling). The second allows the LCD to | 50 | * don't start thinking about scrolling). The second allows the LCD to |
| 53 | * be turned on or off as well as rotated 180 degrees. | 51 | * be turned on or off as well as rotated 180 degrees. |
| 52 | * | ||
| 53 | * In case of direct PLB access the second control register will be at | ||
| 54 | * an offset of 4 as compared to the DCR access where the offset is 1 | ||
| 55 | * i.e. REG_CTRL. So this is taken care in the function | ||
| 56 | * xilinx_fb_out_be32 where it left shifts the offset 2 times in case of | ||
| 57 | * direct PLB access. | ||
| 54 | */ | 58 | */ |
| 55 | #define NUM_REGS 2 | 59 | #define NUM_REGS 2 |
| 56 | #define REG_FB_ADDR 0 | 60 | #define REG_FB_ADDR 0 |
| @@ -107,17 +111,28 @@ static struct fb_var_screeninfo xilinx_fb_var = { | |||
| 107 | .activate = FB_ACTIVATE_NOW | 111 | .activate = FB_ACTIVATE_NOW |
| 108 | }; | 112 | }; |
| 109 | 113 | ||
| 114 | |||
| 115 | #define PLB_ACCESS_FLAG 0x1 /* 1 = PLB, 0 = DCR */ | ||
| 116 | |||
| 110 | struct xilinxfb_drvdata { | 117 | struct xilinxfb_drvdata { |
| 111 | 118 | ||
| 112 | struct fb_info info; /* FB driver info record */ | 119 | struct fb_info info; /* FB driver info record */ |
| 113 | 120 | ||
| 114 | u32 regs_phys; /* phys. address of the control registers */ | 121 | phys_addr_t regs_phys; /* phys. address of the control |
| 115 | u32 __iomem *regs; /* virt. address of the control registers */ | 122 | registers */ |
| 123 | void __iomem *regs; /* virt. address of the control | ||
| 124 | registers */ | ||
| 125 | |||
| 126 | dcr_host_t dcr_host; | ||
| 127 | unsigned int dcr_start; | ||
| 128 | unsigned int dcr_len; | ||
| 116 | 129 | ||
| 117 | void *fb_virt; /* virt. address of the frame buffer */ | 130 | void *fb_virt; /* virt. address of the frame buffer */ |
| 118 | dma_addr_t fb_phys; /* phys. address of the frame buffer */ | 131 | dma_addr_t fb_phys; /* phys. address of the frame buffer */ |
| 119 | int fb_alloced; /* Flag, was the fb memory alloced? */ | 132 | int fb_alloced; /* Flag, was the fb memory alloced? */ |
| 120 | 133 | ||
| 134 | u8 flags; /* features of the driver */ | ||
| 135 | |||
| 121 | u32 reg_ctrl_default; | 136 | u32 reg_ctrl_default; |
| 122 | 137 | ||
| 123 | u32 pseudo_palette[PALETTE_ENTRIES_NO]; | 138 | u32 pseudo_palette[PALETTE_ENTRIES_NO]; |
| @@ -128,14 +143,19 @@ struct xilinxfb_drvdata { | |||
| 128 | container_of(_info, struct xilinxfb_drvdata, info) | 143 | container_of(_info, struct xilinxfb_drvdata, info) |
| 129 | 144 | ||
| 130 | /* | 145 | /* |
| 131 | * The LCD controller has DCR interface to its registers, but all | 146 | * The XPS TFT Controller can be accessed through PLB or DCR interface. |
| 132 | * the boards and configurations the driver has been tested with | 147 | * To perform the read/write on the registers we need to check on |
| 133 | * use opb2dcr bridge. So the registers are seen as memory mapped. | 148 | * which bus its connected and call the appropriate write API. |
| 134 | * This macro is to make it simple to add the direct DCR access | ||
| 135 | * when it's needed. | ||
| 136 | */ | 149 | */ |
| 137 | #define xilinx_fb_out_be32(driverdata, offset, val) \ | 150 | static void xilinx_fb_out_be32(struct xilinxfb_drvdata *drvdata, u32 offset, |
| 138 | out_be32(driverdata->regs + offset, val) | 151 | u32 val) |
| 152 | { | ||
| 153 | if (drvdata->flags & PLB_ACCESS_FLAG) | ||
| 154 | out_be32(drvdata->regs + (offset << 2), val); | ||
| 155 | else | ||
| 156 | dcr_write(drvdata->dcr_host, offset, val); | ||
| 157 | |||
| 158 | } | ||
| 139 | 159 | ||
| 140 | static int | 160 | static int |
| 141 | xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, | 161 | xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, |
| @@ -203,35 +223,34 @@ static struct fb_ops xilinxfb_ops = | |||
| 203 | * Bus independent setup/teardown | 223 | * Bus independent setup/teardown |
| 204 | */ | 224 | */ |
| 205 | 225 | ||
| 206 | static int xilinxfb_assign(struct device *dev, unsigned long physaddr, | 226 | static int xilinxfb_assign(struct device *dev, |
| 227 | struct xilinxfb_drvdata *drvdata, | ||
| 228 | unsigned long physaddr, | ||
| 207 | struct xilinxfb_platform_data *pdata) | 229 | struct xilinxfb_platform_data *pdata) |
| 208 | { | 230 | { |
| 209 | struct xilinxfb_drvdata *drvdata; | ||
| 210 | int rc; | 231 | int rc; |
| 211 | int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL; | 232 | int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL; |
| 212 | 233 | ||
| 213 | /* Allocate the driver data region */ | 234 | if (drvdata->flags & PLB_ACCESS_FLAG) { |
| 214 | drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); | 235 | /* |
| 215 | if (!drvdata) { | 236 | * Map the control registers in if the controller |
| 216 | dev_err(dev, "Couldn't allocate device private record\n"); | 237 | * is on direct PLB interface. |
| 217 | return -ENOMEM; | 238 | */ |
| 218 | } | 239 | if (!request_mem_region(physaddr, 8, DRIVER_NAME)) { |
| 219 | dev_set_drvdata(dev, drvdata); | 240 | dev_err(dev, "Couldn't lock memory region at 0x%08lX\n", |
| 220 | 241 | physaddr); | |
| 221 | /* Map the control registers in */ | 242 | rc = -ENODEV; |
| 222 | if (!request_mem_region(physaddr, 8, DRIVER_NAME)) { | 243 | goto err_region; |
| 223 | dev_err(dev, "Couldn't lock memory region at 0x%08lX\n", | 244 | } |
| 224 | physaddr); | 245 | |
| 225 | rc = -ENODEV; | 246 | drvdata->regs_phys = physaddr; |
| 226 | goto err_region; | 247 | drvdata->regs = ioremap(physaddr, 8); |
| 227 | } | 248 | if (!drvdata->regs) { |
| 228 | drvdata->regs_phys = physaddr; | 249 | dev_err(dev, "Couldn't lock memory region at 0x%08lX\n", |
| 229 | drvdata->regs = ioremap(physaddr, 8); | 250 | physaddr); |
| 230 | if (!drvdata->regs) { | 251 | rc = -ENODEV; |
| 231 | dev_err(dev, "Couldn't lock memory region at 0x%08lX\n", | 252 | goto err_map; |
| 232 | physaddr); | 253 | } |
| 233 | rc = -ENODEV; | ||
| 234 | goto err_map; | ||
| 235 | } | 254 | } |
| 236 | 255 | ||
| 237 | /* Allocate the framebuffer memory */ | 256 | /* Allocate the framebuffer memory */ |
| @@ -247,7 +266,10 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, | |||
| 247 | if (!drvdata->fb_virt) { | 266 | if (!drvdata->fb_virt) { |
| 248 | dev_err(dev, "Could not allocate frame buffer memory\n"); | 267 | dev_err(dev, "Could not allocate frame buffer memory\n"); |
| 249 | rc = -ENOMEM; | 268 | rc = -ENOMEM; |
| 250 | goto err_fbmem; | 269 | if (drvdata->flags & PLB_ACCESS_FLAG) |
| 270 | goto err_fbmem; | ||
| 271 | else | ||
| 272 | goto err_region; | ||
| 251 | } | 273 | } |
| 252 | 274 | ||
| 253 | /* Clear (turn to black) the framebuffer */ | 275 | /* Clear (turn to black) the framebuffer */ |
| @@ -260,7 +282,8 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, | |||
| 260 | drvdata->reg_ctrl_default = REG_CTRL_ENABLE; | 282 | drvdata->reg_ctrl_default = REG_CTRL_ENABLE; |
| 261 | if (pdata->rotate_screen) | 283 | if (pdata->rotate_screen) |
| 262 | drvdata->reg_ctrl_default |= REG_CTRL_ROTATE; | 284 | drvdata->reg_ctrl_default |= REG_CTRL_ROTATE; |
| 263 | xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default); | 285 | xilinx_fb_out_be32(drvdata, REG_CTRL, |
| 286 | drvdata->reg_ctrl_default); | ||
| 264 | 287 | ||
| 265 | /* Fill struct fb_info */ | 288 | /* Fill struct fb_info */ |
| 266 | drvdata->info.device = dev; | 289 | drvdata->info.device = dev; |
| @@ -296,11 +319,14 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, | |||
| 296 | goto err_regfb; | 319 | goto err_regfb; |
| 297 | } | 320 | } |
| 298 | 321 | ||
| 322 | if (drvdata->flags & PLB_ACCESS_FLAG) { | ||
| 323 | /* Put a banner in the log (for DEBUG) */ | ||
| 324 | dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, | ||
| 325 | drvdata->regs); | ||
| 326 | } | ||
| 299 | /* Put a banner in the log (for DEBUG) */ | 327 | /* Put a banner in the log (for DEBUG) */ |
| 300 | dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, drvdata->regs); | 328 | dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n", |
| 301 | dev_dbg(dev, "fb: phys=%llx, virt=%p, size=%x\n", | 329 | (void *)drvdata->fb_phys, drvdata->fb_virt, fbsize); |
| 302 | (unsigned long long) drvdata->fb_phys, drvdata->fb_virt, | ||
| 303 | fbsize); | ||
| 304 | 330 | ||
| 305 | return 0; /* success */ | 331 | return 0; /* success */ |
| 306 | 332 | ||
| @@ -311,14 +337,19 @@ err_cmap: | |||
| 311 | if (drvdata->fb_alloced) | 337 | if (drvdata->fb_alloced) |
| 312 | dma_free_coherent(dev, PAGE_ALIGN(fbsize), drvdata->fb_virt, | 338 | dma_free_coherent(dev, PAGE_ALIGN(fbsize), drvdata->fb_virt, |
| 313 | drvdata->fb_phys); | 339 | drvdata->fb_phys); |
| 340 | else | ||
| 341 | iounmap(drvdata->fb_virt); | ||
| 342 | |||
| 314 | /* Turn off the display */ | 343 | /* Turn off the display */ |
| 315 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); | 344 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); |
| 316 | 345 | ||
| 317 | err_fbmem: | 346 | err_fbmem: |
| 318 | iounmap(drvdata->regs); | 347 | if (drvdata->flags & PLB_ACCESS_FLAG) |
| 348 | iounmap(drvdata->regs); | ||
| 319 | 349 | ||
| 320 | err_map: | 350 | err_map: |
| 321 | release_mem_region(physaddr, 8); | 351 | if (drvdata->flags & PLB_ACCESS_FLAG) |
| 352 | release_mem_region(physaddr, 8); | ||
| 322 | 353 | ||
| 323 | err_region: | 354 | err_region: |
| 324 | kfree(drvdata); | 355 | kfree(drvdata); |
| @@ -342,12 +373,18 @@ static int xilinxfb_release(struct device *dev) | |||
| 342 | if (drvdata->fb_alloced) | 373 | if (drvdata->fb_alloced) |
| 343 | dma_free_coherent(dev, PAGE_ALIGN(drvdata->info.fix.smem_len), | 374 | dma_free_coherent(dev, PAGE_ALIGN(drvdata->info.fix.smem_len), |
| 344 | drvdata->fb_virt, drvdata->fb_phys); | 375 | drvdata->fb_virt, drvdata->fb_phys); |
| 376 | else | ||
| 377 | iounmap(drvdata->fb_virt); | ||
| 345 | 378 | ||
| 346 | /* Turn off the display */ | 379 | /* Turn off the display */ |
| 347 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); | 380 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); |
| 348 | iounmap(drvdata->regs); | ||
| 349 | 381 | ||
| 350 | release_mem_region(drvdata->regs_phys, 8); | 382 | /* Release the resources, as allocated based on interface */ |
| 383 | if (drvdata->flags & PLB_ACCESS_FLAG) { | ||
| 384 | iounmap(drvdata->regs); | ||
| 385 | release_mem_region(drvdata->regs_phys, 8); | ||
| 386 | } else | ||
| 387 | dcr_unmap(drvdata->dcr_host, drvdata->dcr_len); | ||
| 351 | 388 | ||
| 352 | kfree(drvdata); | 389 | kfree(drvdata); |
| 353 | dev_set_drvdata(dev, NULL); | 390 | dev_set_drvdata(dev, NULL); |
| @@ -356,77 +393,57 @@ static int xilinxfb_release(struct device *dev) | |||
| 356 | } | 393 | } |
| 357 | 394 | ||
| 358 | /* --------------------------------------------------------------------- | 395 | /* --------------------------------------------------------------------- |
| 359 | * Platform bus binding | ||
| 360 | */ | ||
| 361 | |||
| 362 | static int | ||
| 363 | xilinxfb_platform_probe(struct platform_device *pdev) | ||
| 364 | { | ||
| 365 | struct xilinxfb_platform_data *pdata; | ||
| 366 | struct resource *res; | ||
| 367 | |||
| 368 | /* Find the registers address */ | ||
| 369 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
| 370 | if (!res) { | ||
| 371 | dev_err(&pdev->dev, "Couldn't get registers resource\n"); | ||
| 372 | return -ENODEV; | ||
| 373 | } | ||
| 374 | |||
| 375 | /* If a pdata structure is provided, then extract the parameters */ | ||
| 376 | pdata = &xilinx_fb_default_pdata; | ||
| 377 | if (pdev->dev.platform_data) { | ||
| 378 | pdata = pdev->dev.platform_data; | ||
| 379 | if (!pdata->xres) | ||
| 380 | pdata->xres = xilinx_fb_default_pdata.xres; | ||
| 381 | if (!pdata->yres) | ||
| 382 | pdata->yres = xilinx_fb_default_pdata.yres; | ||
| 383 | if (!pdata->xvirt) | ||
| 384 | pdata->xvirt = xilinx_fb_default_pdata.xvirt; | ||
| 385 | if (!pdata->yvirt) | ||
| 386 | pdata->yvirt = xilinx_fb_default_pdata.yvirt; | ||
| 387 | } | ||
| 388 | |||
| 389 | return xilinxfb_assign(&pdev->dev, res->start, pdata); | ||
| 390 | } | ||
| 391 | |||
| 392 | static int | ||
| 393 | xilinxfb_platform_remove(struct platform_device *pdev) | ||
| 394 | { | ||
| 395 | return xilinxfb_release(&pdev->dev); | ||
| 396 | } | ||
| 397 | |||
| 398 | |||
| 399 | static struct platform_driver xilinxfb_platform_driver = { | ||
| 400 | .probe = xilinxfb_platform_probe, | ||
| 401 | .remove = xilinxfb_platform_remove, | ||
| 402 | .driver = { | ||
| 403 | .owner = THIS_MODULE, | ||
| 404 | .name = DRIVER_NAME, | ||
| 405 | }, | ||
| 406 | }; | ||
| 407 | |||
| 408 | /* --------------------------------------------------------------------- | ||
| 409 | * OF bus binding | 396 | * OF bus binding |
| 410 | */ | 397 | */ |
| 411 | 398 | ||
| 412 | #if defined(CONFIG_OF) | ||
| 413 | static int __devinit | 399 | static int __devinit |
| 414 | xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) | 400 | xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) |
| 415 | { | 401 | { |
| 416 | struct resource res; | ||
| 417 | const u32 *prop; | 402 | const u32 *prop; |
| 403 | u32 *p; | ||
| 404 | u32 tft_access; | ||
| 418 | struct xilinxfb_platform_data pdata; | 405 | struct xilinxfb_platform_data pdata; |
| 406 | struct resource res; | ||
| 419 | int size, rc; | 407 | int size, rc; |
| 408 | int start = 0, len = 0; | ||
| 409 | dcr_host_t dcr_host; | ||
| 410 | struct xilinxfb_drvdata *drvdata; | ||
| 420 | 411 | ||
| 421 | /* Copy with the default pdata (not a ptr reference!) */ | 412 | /* Copy with the default pdata (not a ptr reference!) */ |
| 422 | pdata = xilinx_fb_default_pdata; | 413 | pdata = xilinx_fb_default_pdata; |
| 423 | 414 | ||
| 424 | dev_dbg(&op->dev, "xilinxfb_of_probe(%p, %p)\n", op, match); | 415 | dev_dbg(&op->dev, "xilinxfb_of_probe(%p, %p)\n", op, match); |
| 425 | 416 | ||
| 426 | rc = of_address_to_resource(op->node, 0, &res); | 417 | /* |
| 427 | if (rc) { | 418 | * To check whether the core is connected directly to DCR or PLB |
| 428 | dev_err(&op->dev, "invalid address\n"); | 419 | * interface and initialize the tft_access accordingly. |
| 429 | return rc; | 420 | */ |
| 421 | p = (u32 *)of_get_property(op->node, "xlnx,dcr-splb-slave-if", NULL); | ||
| 422 | |||
| 423 | if (p) | ||
| 424 | tft_access = *p; | ||
| 425 | else | ||
| 426 | tft_access = 0; /* For backward compatibility */ | ||
| 427 | |||
| 428 | /* | ||
| 429 | * Fill the resource structure if its direct PLB interface | ||
| 430 | * otherwise fill the dcr_host structure. | ||
| 431 | */ | ||
| 432 | if (tft_access) { | ||
| 433 | rc = of_address_to_resource(op->node, 0, &res); | ||
| 434 | if (rc) { | ||
| 435 | dev_err(&op->dev, "invalid address\n"); | ||
| 436 | return -ENODEV; | ||
| 437 | } | ||
| 438 | |||
| 439 | } else { | ||
| 440 | start = dcr_resource_start(op->node, 0); | ||
| 441 | len = dcr_resource_len(op->node, 0); | ||
| 442 | dcr_host = dcr_map(op->node, start, len); | ||
| 443 | if (!DCR_MAP_OK(dcr_host)) { | ||
| 444 | dev_err(&op->dev, "invalid address\n"); | ||
| 445 | return -ENODEV; | ||
| 446 | } | ||
| 430 | } | 447 | } |
| 431 | 448 | ||
| 432 | prop = of_get_property(op->node, "phys-size", &size); | 449 | prop = of_get_property(op->node, "phys-size", &size); |
| @@ -450,7 +467,26 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) | |||
| 450 | if (of_find_property(op->node, "rotate-display", NULL)) | 467 | if (of_find_property(op->node, "rotate-display", NULL)) |
| 451 | pdata.rotate_screen = 1; | 468 | pdata.rotate_screen = 1; |
| 452 | 469 | ||
| 453 | return xilinxfb_assign(&op->dev, res.start, &pdata); | 470 | /* Allocate the driver data region */ |
| 471 | drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); | ||
| 472 | if (!drvdata) { | ||
| 473 | dev_err(&op->dev, "Couldn't allocate device private record\n"); | ||
| 474 | return -ENOMEM; | ||
| 475 | } | ||
| 476 | dev_set_drvdata(&op->dev, drvdata); | ||
| 477 | |||
| 478 | if (tft_access) | ||
| 479 | drvdata->flags |= PLB_ACCESS_FLAG; | ||
| 480 | |||
| 481 | /* Arguments are passed based on the interface */ | ||
| 482 | if (drvdata->flags & PLB_ACCESS_FLAG) { | ||
| 483 | return xilinxfb_assign(&op->dev, drvdata, res.start, &pdata); | ||
| 484 | } else { | ||
| 485 | drvdata->dcr_start = start; | ||
| 486 | drvdata->dcr_len = len; | ||
| 487 | drvdata->dcr_host = dcr_host; | ||
| 488 | return xilinxfb_assign(&op->dev, drvdata, 0, &pdata); | ||
| 489 | } | ||
| 454 | } | 490 | } |
| 455 | 491 | ||
| 456 | static int __devexit xilinxfb_of_remove(struct of_device *op) | 492 | static int __devexit xilinxfb_of_remove(struct of_device *op) |
| @@ -460,7 +496,9 @@ static int __devexit xilinxfb_of_remove(struct of_device *op) | |||
| 460 | 496 | ||
| 461 | /* Match table for of_platform binding */ | 497 | /* Match table for of_platform binding */ |
| 462 | static struct of_device_id xilinxfb_of_match[] __devinitdata = { | 498 | static struct of_device_id xilinxfb_of_match[] __devinitdata = { |
| 499 | { .compatible = "xlnx,xps-tft-1.00.a", }, | ||
| 463 | { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", }, | 500 | { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", }, |
| 501 | { .compatible = "xlnx,plb-dvi-cntlr-ref-1.00.c", }, | ||
| 464 | {}, | 502 | {}, |
| 465 | }; | 503 | }; |
| 466 | MODULE_DEVICE_TABLE(of, xilinxfb_of_match); | 504 | MODULE_DEVICE_TABLE(of, xilinxfb_of_match); |
| @@ -476,22 +514,6 @@ static struct of_platform_driver xilinxfb_of_driver = { | |||
| 476 | }, | 514 | }, |
| 477 | }; | 515 | }; |
| 478 | 516 | ||
| 479 | /* Registration helpers to keep the number of #ifdefs to a minimum */ | ||
| 480 | static inline int __init xilinxfb_of_register(void) | ||
| 481 | { | ||
| 482 | pr_debug("xilinxfb: calling of_register_platform_driver()\n"); | ||
| 483 | return of_register_platform_driver(&xilinxfb_of_driver); | ||
| 484 | } | ||
| 485 | |||
| 486 | static inline void __exit xilinxfb_of_unregister(void) | ||
| 487 | { | ||
| 488 | of_unregister_platform_driver(&xilinxfb_of_driver); | ||
| 489 | } | ||
| 490 | #else /* CONFIG_OF */ | ||
| 491 | /* CONFIG_OF not enabled; do nothing helpers */ | ||
| 492 | static inline int __init xilinxfb_of_register(void) { return 0; } | ||
| 493 | static inline void __exit xilinxfb_of_unregister(void) { } | ||
| 494 | #endif /* CONFIG_OF */ | ||
| 495 | 517 | ||
| 496 | /* --------------------------------------------------------------------- | 518 | /* --------------------------------------------------------------------- |
| 497 | * Module setup and teardown | 519 | * Module setup and teardown |
| @@ -500,28 +522,18 @@ static inline void __exit xilinxfb_of_unregister(void) { } | |||
| 500 | static int __init | 522 | static int __init |
| 501 | xilinxfb_init(void) | 523 | xilinxfb_init(void) |
| 502 | { | 524 | { |
| 503 | int rc; | 525 | return of_register_platform_driver(&xilinxfb_of_driver); |
| 504 | rc = xilinxfb_of_register(); | ||
| 505 | if (rc) | ||
| 506 | return rc; | ||
| 507 | |||
| 508 | rc = platform_driver_register(&xilinxfb_platform_driver); | ||
| 509 | if (rc) | ||
| 510 | xilinxfb_of_unregister(); | ||
| 511 | |||
| 512 | return rc; | ||
| 513 | } | 526 | } |
| 514 | 527 | ||
| 515 | static void __exit | 528 | static void __exit |
| 516 | xilinxfb_cleanup(void) | 529 | xilinxfb_cleanup(void) |
| 517 | { | 530 | { |
| 518 | platform_driver_unregister(&xilinxfb_platform_driver); | 531 | of_unregister_platform_driver(&xilinxfb_of_driver); |
| 519 | xilinxfb_of_unregister(); | ||
| 520 | } | 532 | } |
| 521 | 533 | ||
| 522 | module_init(xilinxfb_init); | 534 | module_init(xilinxfb_init); |
| 523 | module_exit(xilinxfb_cleanup); | 535 | module_exit(xilinxfb_cleanup); |
| 524 | 536 | ||
| 525 | MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>"); | 537 | MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>"); |
| 526 | MODULE_DESCRIPTION(DRIVER_DESCRIPTION); | 538 | MODULE_DESCRIPTION("Xilinx TFT frame buffer driver"); |
| 527 | MODULE_LICENSE("GPL"); | 539 | MODULE_LICENSE("GPL"); |
