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"); |