diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-20 12:13:34 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-20 12:13:34 -0400 |
| commit | ed402af3c23a4804b3f8899263e8d0f97c62ab49 (patch) | |
| tree | 3aa971aea57f900a3060cc0545b199ef611f4dcf /drivers | |
| parent | 096e6f673dc02a6394dc9a7d8f8735c6978f5b91 (diff) | |
| parent | 40e24c403f325715f9c43b9fed2068641201ee0b (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (112 commits)
sh: Move SH-4 CPU headers down one more level.
sh: Only build in gpio.o when CONFIG_GENERIC_GPIO is selected.
sh: Migrate common board headers to mach-common/.
sh: Move the CPU definition headers from asm/ to cpu/.
serial: sh-sci: Add support SCIF of SH7723
video: add sh_mobile_lcdc platform flags
video: remove unused sh_mobile_lcdc platform data
sh: remove consistent alloc cruft
sh: add dynamic crash base address support
sh: reduce Migo-R smc91x overruns
sh: Fix up some merge damage.
Fix debugfs_create_file's error checking method for arch/sh/mm/
Fix debugfs_create_dir's error checking method for arch/sh/kernel/
sh: ap325rxa: Add support RTC RX-8564LC in AP325RXA board
sh: Use sh7720 GPIO on magicpanelr2 board
sh: Add sh7720 pinmux code
sh: Use sh7203 GPIO on rsk7203 board
sh: Add sh7203 pinmux code
sh: Use sh7723 GPIO on AP325RXA board
sh: Add sh7723 pinmux code
...
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/input/touchscreen/hp680_ts_input.c | 2 | ||||
| -rw-r--r-- | drivers/leds/leds-hp6xx.c | 2 | ||||
| -rw-r--r-- | drivers/net/sh_eth.c | 5 | ||||
| -rw-r--r-- | drivers/rtc/rtc-ds1302.c | 2 | ||||
| -rw-r--r-- | drivers/rtc/rtc-sh.c | 21 | ||||
| -rw-r--r-- | drivers/serial/sh-sci.c | 90 | ||||
| -rw-r--r-- | drivers/serial/sh-sci.h | 23 | ||||
| -rw-r--r-- | drivers/sh/Makefile | 2 | ||||
| -rw-r--r-- | drivers/sh/intc.c | 713 | ||||
| -rw-r--r-- | drivers/video/backlight/hp680_bl.c | 2 | ||||
| -rw-r--r-- | drivers/video/sh_mobile_lcdcfb.c | 14 |
11 files changed, 809 insertions, 67 deletions
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index c38d4e0f95c6..a89700e7ace4 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | #include <asm/io.h> | 5 | #include <asm/io.h> |
| 6 | #include <asm/delay.h> | 6 | #include <asm/delay.h> |
| 7 | #include <asm/adc.h> | 7 | #include <asm/adc.h> |
| 8 | #include <asm/hp6xx.h> | 8 | #include <mach/hp6xx.h> |
| 9 | 9 | ||
| 10 | #define MODNAME "hp680_ts_input" | 10 | #define MODNAME "hp680_ts_input" |
| 11 | 11 | ||
diff --git a/drivers/leds/leds-hp6xx.c b/drivers/leds/leds-hp6xx.c index 844d5979c904..e8fb1baf8a50 100644 --- a/drivers/leds/leds-hp6xx.c +++ b/drivers/leds/leds-hp6xx.c | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
| 16 | #include <linux/leds.h> | 16 | #include <linux/leds.h> |
| 17 | #include <asm/hd64461.h> | 17 | #include <asm/hd64461.h> |
| 18 | #include <asm/hp6xx.h> | 18 | #include <mach/hp6xx.h> |
| 19 | 19 | ||
| 20 | static void hp6xxled_green_set(struct led_classdev *led_cdev, | 20 | static void hp6xxled_green_set(struct led_classdev *led_cdev, |
| 21 | enum led_brightness value) | 21 | enum led_brightness value) |
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index b39d1cc1ef04..a24bb68887ab 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c | |||
| @@ -1205,11 +1205,12 @@ static int sh_eth_drv_probe(struct platform_device *pdev) | |||
| 1205 | devno = 0; | 1205 | devno = 0; |
| 1206 | 1206 | ||
| 1207 | ndev->dma = -1; | 1207 | ndev->dma = -1; |
| 1208 | ndev->irq = platform_get_irq(pdev, 0); | 1208 | ret = platform_get_irq(pdev, 0); |
| 1209 | if (ndev->irq < 0) { | 1209 | if (ret < 0) { |
| 1210 | ret = -ENODEV; | 1210 | ret = -ENODEV; |
| 1211 | goto out_release; | 1211 | goto out_release; |
| 1212 | } | 1212 | } |
| 1213 | ndev->irq = ret; | ||
| 1213 | 1214 | ||
| 1214 | SET_NETDEV_DEV(ndev, &pdev->dev); | 1215 | SET_NETDEV_DEV(ndev, &pdev->dev); |
| 1215 | 1216 | ||
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 16bdba6a6b0c..184556620778 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c | |||
| @@ -40,7 +40,7 @@ | |||
| 40 | #define RTC_SCLK 0x0400 | 40 | #define RTC_SCLK 0x0400 |
| 41 | 41 | ||
| 42 | #ifdef CONFIG_SH_SECUREEDGE5410 | 42 | #ifdef CONFIG_SH_SECUREEDGE5410 |
| 43 | #include <asm/snapgear.h> | 43 | #include <mach/snapgear.h> |
| 44 | #define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) | 44 | #define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) |
| 45 | #define get_dp() SECUREEDGE_READ_IOPORT() | 45 | #define get_dp() SECUREEDGE_READ_IOPORT() |
| 46 | #else | 46 | #else |
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 1ec297128ea6..aaf9d6a337cc 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
| @@ -568,7 +568,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
| 568 | struct sh_rtc *rtc; | 568 | struct sh_rtc *rtc; |
| 569 | struct resource *res; | 569 | struct resource *res; |
| 570 | unsigned int tmp; | 570 | unsigned int tmp; |
| 571 | int ret = -ENOENT; | 571 | int ret; |
| 572 | 572 | ||
| 573 | rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); | 573 | rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); |
| 574 | if (unlikely(!rtc)) | 574 | if (unlikely(!rtc)) |
| @@ -577,26 +577,33 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
| 577 | spin_lock_init(&rtc->lock); | 577 | spin_lock_init(&rtc->lock); |
| 578 | 578 | ||
| 579 | /* get periodic/carry/alarm irqs */ | 579 | /* get periodic/carry/alarm irqs */ |
| 580 | rtc->periodic_irq = platform_get_irq(pdev, 0); | 580 | ret = platform_get_irq(pdev, 0); |
| 581 | if (unlikely(rtc->periodic_irq < 0)) { | 581 | if (unlikely(ret < 0)) { |
| 582 | ret = -ENOENT; | ||
| 582 | dev_err(&pdev->dev, "No IRQ for period\n"); | 583 | dev_err(&pdev->dev, "No IRQ for period\n"); |
| 583 | goto err_badres; | 584 | goto err_badres; |
| 584 | } | 585 | } |
| 586 | rtc->periodic_irq = ret; | ||
| 585 | 587 | ||
| 586 | rtc->carry_irq = platform_get_irq(pdev, 1); | 588 | ret = platform_get_irq(pdev, 1); |
| 587 | if (unlikely(rtc->carry_irq < 0)) { | 589 | if (unlikely(ret < 0)) { |
| 590 | ret = -ENOENT; | ||
| 588 | dev_err(&pdev->dev, "No IRQ for carry\n"); | 591 | dev_err(&pdev->dev, "No IRQ for carry\n"); |
| 589 | goto err_badres; | 592 | goto err_badres; |
| 590 | } | 593 | } |
| 594 | rtc->carry_irq = ret; | ||
| 591 | 595 | ||
| 592 | rtc->alarm_irq = platform_get_irq(pdev, 2); | 596 | ret = platform_get_irq(pdev, 2); |
| 593 | if (unlikely(rtc->alarm_irq < 0)) { | 597 | if (unlikely(ret < 0)) { |
| 598 | ret = -ENOENT; | ||
| 594 | dev_err(&pdev->dev, "No IRQ for alarm\n"); | 599 | dev_err(&pdev->dev, "No IRQ for alarm\n"); |
| 595 | goto err_badres; | 600 | goto err_badres; |
| 596 | } | 601 | } |
| 602 | rtc->alarm_irq = ret; | ||
| 597 | 603 | ||
| 598 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 604 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 599 | if (unlikely(res == NULL)) { | 605 | if (unlikely(res == NULL)) { |
| 606 | ret = -ENOENT; | ||
| 600 | dev_err(&pdev->dev, "No IO resource\n"); | 607 | dev_err(&pdev->dev, "No IO resource\n"); |
| 601 | goto err_badres; | 608 | goto err_badres; |
| 602 | } | 609 | } |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 3df2aaec829f..3b9d2d83b590 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO) | 4 | * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO) |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2002 - 2006 Paul Mundt | 6 | * Copyright (C) 2002 - 2008 Paul Mundt |
| 7 | * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Jul 2007). | 7 | * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Jul 2007). |
| 8 | * | 8 | * |
| 9 | * based off of the old drivers/char/sh-sci.c by: | 9 | * based off of the old drivers/char/sh-sci.c by: |
| @@ -46,6 +46,7 @@ | |||
| 46 | #include <linux/cpufreq.h> | 46 | #include <linux/cpufreq.h> |
| 47 | #include <linux/clk.h> | 47 | #include <linux/clk.h> |
| 48 | #include <linux/ctype.h> | 48 | #include <linux/ctype.h> |
| 49 | #include <linux/err.h> | ||
| 49 | 50 | ||
| 50 | #ifdef CONFIG_SUPERH | 51 | #ifdef CONFIG_SUPERH |
| 51 | #include <asm/clock.h> | 52 | #include <asm/clock.h> |
| @@ -78,7 +79,7 @@ struct sci_port { | |||
| 78 | struct timer_list break_timer; | 79 | struct timer_list break_timer; |
| 79 | int break_flag; | 80 | int break_flag; |
| 80 | 81 | ||
| 81 | #ifdef CONFIG_SUPERH | 82 | #ifdef CONFIG_HAVE_CLK |
| 82 | /* Port clock */ | 83 | /* Port clock */ |
| 83 | struct clk *clk; | 84 | struct clk *clk; |
| 84 | #endif | 85 | #endif |
| @@ -831,7 +832,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
| 831 | return IRQ_HANDLED; | 832 | return IRQ_HANDLED; |
| 832 | } | 833 | } |
| 833 | 834 | ||
| 834 | #ifdef CONFIG_CPU_FREQ | 835 | #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK) |
| 835 | /* | 836 | /* |
| 836 | * Here we define a transistion notifier so that we can update all of our | 837 | * Here we define a transistion notifier so that we can update all of our |
| 837 | * ports' baud rate when the peripheral clock changes. | 838 | * ports' baud rate when the peripheral clock changes. |
| @@ -860,7 +861,7 @@ static int sci_notifier(struct notifier_block *self, | |||
| 860 | * Clean this up later.. | 861 | * Clean this up later.. |
| 861 | */ | 862 | */ |
| 862 | clk = clk_get(NULL, "module_clk"); | 863 | clk = clk_get(NULL, "module_clk"); |
| 863 | port->uartclk = clk_get_rate(clk) * 16; | 864 | port->uartclk = clk_get_rate(clk); |
| 864 | clk_put(clk); | 865 | clk_put(clk); |
| 865 | } | 866 | } |
| 866 | 867 | ||
| @@ -873,7 +874,7 @@ static int sci_notifier(struct notifier_block *self, | |||
| 873 | } | 874 | } |
| 874 | 875 | ||
| 875 | static struct notifier_block sci_nb = { &sci_notifier, NULL, 0 }; | 876 | static struct notifier_block sci_nb = { &sci_notifier, NULL, 0 }; |
| 876 | #endif /* CONFIG_CPU_FREQ */ | 877 | #endif /* CONFIG_CPU_FREQ && CONFIG_HAVE_CLK */ |
| 877 | 878 | ||
| 878 | static int sci_request_irq(struct sci_port *port) | 879 | static int sci_request_irq(struct sci_port *port) |
| 879 | { | 880 | { |
| @@ -1008,7 +1009,7 @@ static int sci_startup(struct uart_port *port) | |||
| 1008 | if (s->enable) | 1009 | if (s->enable) |
| 1009 | s->enable(port); | 1010 | s->enable(port); |
| 1010 | 1011 | ||
| 1011 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | 1012 | #ifdef CONFIG_HAVE_CLK |
| 1012 | s->clk = clk_get(NULL, "module_clk"); | 1013 | s->clk = clk_get(NULL, "module_clk"); |
| 1013 | #endif | 1014 | #endif |
| 1014 | 1015 | ||
| @@ -1030,7 +1031,7 @@ static void sci_shutdown(struct uart_port *port) | |||
| 1030 | if (s->disable) | 1031 | if (s->disable) |
| 1031 | s->disable(port); | 1032 | s->disable(port); |
| 1032 | 1033 | ||
| 1033 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | 1034 | #ifdef CONFIG_HAVE_CLK |
| 1034 | clk_put(s->clk); | 1035 | clk_put(s->clk); |
| 1035 | s->clk = NULL; | 1036 | s->clk = NULL; |
| 1036 | #endif | 1037 | #endif |
| @@ -1041,24 +1042,11 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 1041 | { | 1042 | { |
| 1042 | struct sci_port *s = &sci_ports[port->line]; | 1043 | struct sci_port *s = &sci_ports[port->line]; |
| 1043 | unsigned int status, baud, smr_val; | 1044 | unsigned int status, baud, smr_val; |
| 1044 | int t; | 1045 | int t = -1; |
| 1045 | 1046 | ||
| 1046 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 1047 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); |
| 1047 | 1048 | if (likely(baud)) | |
| 1048 | switch (baud) { | 1049 | t = SCBRR_VALUE(baud, port->uartclk); |
| 1049 | case 0: | ||
| 1050 | t = -1; | ||
| 1051 | break; | ||
| 1052 | default: | ||
| 1053 | { | ||
| 1054 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | ||
| 1055 | t = SCBRR_VALUE(baud, clk_get_rate(s->clk)); | ||
| 1056 | #else | ||
| 1057 | t = SCBRR_VALUE(baud); | ||
| 1058 | #endif | ||
| 1059 | break; | ||
| 1060 | } | ||
| 1061 | } | ||
| 1062 | 1050 | ||
| 1063 | do { | 1051 | do { |
| 1064 | status = sci_in(port, SCxSR); | 1052 | status = sci_in(port, SCxSR); |
| @@ -1113,7 +1101,7 @@ static const char *sci_type(struct uart_port *port) | |||
| 1113 | case PORT_IRDA: return "irda"; | 1101 | case PORT_IRDA: return "irda"; |
| 1114 | } | 1102 | } |
| 1115 | 1103 | ||
| 1116 | return 0; | 1104 | return NULL; |
| 1117 | } | 1105 | } |
| 1118 | 1106 | ||
| 1119 | static void sci_release_port(struct uart_port *port) | 1107 | static void sci_release_port(struct uart_port *port) |
| @@ -1145,12 +1133,16 @@ static void sci_config_port(struct uart_port *port, int flags) | |||
| 1145 | break; | 1133 | break; |
| 1146 | } | 1134 | } |
| 1147 | 1135 | ||
| 1148 | #if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) | 1136 | if (port->flags & UPF_IOREMAP && !port->membase) { |
| 1149 | if (port->mapbase == 0) | 1137 | #if defined(CONFIG_SUPERH64) |
| 1150 | port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); | 1138 | port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); |
| 1151 | 1139 | port->membase = (void __iomem *)port->mapbase; | |
| 1152 | port->membase = (void __iomem *)port->mapbase; | 1140 | #else |
| 1141 | port->membase = ioremap_nocache(port->mapbase, 0x40); | ||
| 1153 | #endif | 1142 | #endif |
| 1143 | |||
| 1144 | printk(KERN_ERR "sci: can't remap port#%d\n", port->line); | ||
| 1145 | } | ||
| 1154 | } | 1146 | } |
| 1155 | 1147 | ||
| 1156 | static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) | 1148 | static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) |
| @@ -1207,17 +1199,17 @@ static void __init sci_init_ports(void) | |||
| 1207 | sci_ports[i].disable = h8300_sci_disable; | 1199 | sci_ports[i].disable = h8300_sci_disable; |
| 1208 | #endif | 1200 | #endif |
| 1209 | sci_ports[i].port.uartclk = CONFIG_CPU_CLOCK; | 1201 | sci_ports[i].port.uartclk = CONFIG_CPU_CLOCK; |
| 1210 | #elif defined(CONFIG_SUPERH64) | 1202 | #elif defined(CONFIG_HAVE_CLK) |
| 1211 | sci_ports[i].port.uartclk = current_cpu_data.module_clock * 16; | ||
| 1212 | #else | ||
| 1213 | /* | 1203 | /* |
| 1214 | * XXX: We should use a proper SCI/SCIF clock | 1204 | * XXX: We should use a proper SCI/SCIF clock |
| 1215 | */ | 1205 | */ |
| 1216 | { | 1206 | { |
| 1217 | struct clk *clk = clk_get(NULL, "module_clk"); | 1207 | struct clk *clk = clk_get(NULL, "module_clk"); |
| 1218 | sci_ports[i].port.uartclk = clk_get_rate(clk) * 16; | 1208 | sci_ports[i].port.uartclk = clk_get_rate(clk); |
| 1219 | clk_put(clk); | 1209 | clk_put(clk); |
| 1220 | } | 1210 | } |
| 1211 | #else | ||
| 1212 | #error "Need a valid uartclk" | ||
| 1221 | #endif | 1213 | #endif |
| 1222 | 1214 | ||
| 1223 | sci_ports[i].break_timer.data = (unsigned long)&sci_ports[i]; | 1215 | sci_ports[i].break_timer.data = (unsigned long)&sci_ports[i]; |
| @@ -1285,7 +1277,7 @@ static int __init serial_console_setup(struct console *co, char *options) | |||
| 1285 | 1277 | ||
| 1286 | port->type = serial_console_port->type; | 1278 | port->type = serial_console_port->type; |
| 1287 | 1279 | ||
| 1288 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | 1280 | #ifdef CONFIG_HAVE_CLK |
| 1289 | if (!serial_console_port->clk) | 1281 | if (!serial_console_port->clk) |
| 1290 | serial_console_port->clk = clk_get(NULL, "module_clk"); | 1282 | serial_console_port->clk = clk_get(NULL, "module_clk"); |
| 1291 | #endif | 1283 | #endif |
| @@ -1436,7 +1428,7 @@ static struct uart_driver sci_uart_driver = { | |||
| 1436 | static int __devinit sci_probe(struct platform_device *dev) | 1428 | static int __devinit sci_probe(struct platform_device *dev) |
| 1437 | { | 1429 | { |
| 1438 | struct plat_sci_port *p = dev->dev.platform_data; | 1430 | struct plat_sci_port *p = dev->dev.platform_data; |
| 1439 | int i; | 1431 | int i, ret = -EINVAL; |
| 1440 | 1432 | ||
| 1441 | for (i = 0; p && p->flags != 0; p++, i++) { | 1433 | for (i = 0; p && p->flags != 0; p++, i++) { |
| 1442 | struct sci_port *sciport = &sci_ports[i]; | 1434 | struct sci_port *sciport = &sci_ports[i]; |
| @@ -1453,12 +1445,22 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
| 1453 | 1445 | ||
| 1454 | sciport->port.mapbase = p->mapbase; | 1446 | sciport->port.mapbase = p->mapbase; |
| 1455 | 1447 | ||
| 1456 | /* | 1448 | if (p->mapbase && !p->membase) { |
| 1457 | * For the simple (and majority of) cases where we don't need | 1449 | if (p->flags & UPF_IOREMAP) { |
| 1458 | * to do any remapping, just cast the cookie directly. | 1450 | p->membase = ioremap_nocache(p->mapbase, 0x40); |
| 1459 | */ | 1451 | if (IS_ERR(p->membase)) { |
| 1460 | if (p->mapbase && !p->membase && !(p->flags & UPF_IOREMAP)) | 1452 | ret = PTR_ERR(p->membase); |
| 1461 | p->membase = (void __iomem *)p->mapbase; | 1453 | goto err_unreg; |
| 1454 | } | ||
| 1455 | } else { | ||
| 1456 | /* | ||
| 1457 | * For the simple (and majority of) cases | ||
| 1458 | * where we don't need to do any remapping, | ||
| 1459 | * just cast the cookie directly. | ||
| 1460 | */ | ||
| 1461 | p->membase = (void __iomem *)p->mapbase; | ||
| 1462 | } | ||
| 1463 | } | ||
| 1462 | 1464 | ||
| 1463 | sciport->port.membase = p->membase; | 1465 | sciport->port.membase = p->membase; |
| 1464 | 1466 | ||
| @@ -1479,7 +1481,7 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
| 1479 | kgdb_putchar = kgdb_sci_putchar; | 1481 | kgdb_putchar = kgdb_sci_putchar; |
| 1480 | #endif | 1482 | #endif |
| 1481 | 1483 | ||
| 1482 | #ifdef CONFIG_CPU_FREQ | 1484 | #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK) |
| 1483 | cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); | 1485 | cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); |
| 1484 | dev_info(&dev->dev, "CPU frequency notifier registered\n"); | 1486 | dev_info(&dev->dev, "CPU frequency notifier registered\n"); |
| 1485 | #endif | 1487 | #endif |
| @@ -1489,6 +1491,12 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
| 1489 | #endif | 1491 | #endif |
| 1490 | 1492 | ||
| 1491 | return 0; | 1493 | return 0; |
| 1494 | |||
| 1495 | err_unreg: | ||
| 1496 | for (i = i - 1; i >= 0; i--) | ||
| 1497 | uart_remove_one_port(&sci_uart_driver, &sci_ports[i].port); | ||
| 1498 | |||
| 1499 | return ret; | ||
| 1492 | } | 1500 | } |
| 1493 | 1501 | ||
| 1494 | static int __devexit sci_remove(struct platform_device *dev) | 1502 | static int __devexit sci_remove(struct platform_device *dev) |
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 8a0749e34ca3..7cd28b226800 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h | |||
| @@ -320,18 +320,16 @@ | |||
| 320 | #define SCI_EVENT_WRITE_WAKEUP 0 | 320 | #define SCI_EVENT_WRITE_WAKEUP 0 |
| 321 | 321 | ||
| 322 | #define SCI_IN(size, offset) \ | 322 | #define SCI_IN(size, offset) \ |
| 323 | unsigned int addr = port->mapbase + (offset); \ | ||
| 324 | if ((size) == 8) { \ | 323 | if ((size) == 8) { \ |
| 325 | return ctrl_inb(addr); \ | 324 | return ioread8(port->membase + (offset)); \ |
| 326 | } else { \ | 325 | } else { \ |
| 327 | return ctrl_inw(addr); \ | 326 | return ioread16(port->membase + (offset)); \ |
| 328 | } | 327 | } |
| 329 | #define SCI_OUT(size, offset, value) \ | 328 | #define SCI_OUT(size, offset, value) \ |
| 330 | unsigned int addr = port->mapbase + (offset); \ | ||
| 331 | if ((size) == 8) { \ | 329 | if ((size) == 8) { \ |
| 332 | ctrl_outb(value, addr); \ | 330 | iowrite8(value, port->membase + (offset)); \ |
| 333 | } else if ((size) == 16) { \ | 331 | } else if ((size) == 16) { \ |
| 334 | ctrl_outw(value, addr); \ | 332 | iowrite16(value, port->membase + (offset)); \ |
| 335 | } | 333 | } |
| 336 | 334 | ||
| 337 | #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ | 335 | #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ |
| @@ -791,11 +789,16 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
| 791 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 789 | defined(CONFIG_CPU_SUBTYPE_SH7721) |
| 792 | #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) | 790 | #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) |
| 793 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) | 791 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) |
| 794 | #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(16*bps)-1) | 792 | static inline int scbrr_calc(struct uart_port *port, int bps, int clk) |
| 793 | { | ||
| 794 | if (port->type == PORT_SCIF) | ||
| 795 | return (clk+16*bps)/(32*bps)-1; | ||
| 796 | else | ||
| 797 | return ((clk*2)+16*bps)/(16*bps)-1; | ||
| 798 | } | ||
| 799 | #define SCBRR_VALUE(bps, clk) scbrr_calc(port, bps, clk) | ||
| 795 | #elif defined(__H8300H__) || defined(__H8300S__) | 800 | #elif defined(__H8300H__) || defined(__H8300S__) |
| 796 | #define SCBRR_VALUE(bps) (((CONFIG_CPU_CLOCK*1000/32)/bps)-1) | 801 | #define SCBRR_VALUE(bps, clk) (((clk*1000/32)/bps)-1) |
| 797 | #elif defined(CONFIG_SUPERH64) | ||
| 798 | #define SCBRR_VALUE(bps) ((current_cpu_data.module_clock+16*bps)/(32*bps)-1) | ||
| 799 | #else /* Generic SH */ | 802 | #else /* Generic SH */ |
| 800 | #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1) | 803 | #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1) |
| 801 | #endif | 804 | #endif |
diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile index a96f4a8cfeb8..6a025cefe6dc 100644 --- a/drivers/sh/Makefile +++ b/drivers/sh/Makefile | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | # | 1 | # |
| 2 | # Makefile for the SuperH specific drivers. | 2 | # Makefile for the SuperH specific drivers. |
| 3 | # | 3 | # |
| 4 | |||
| 5 | obj-$(CONFIG_SUPERHYWAY) += superhyway/ | 4 | obj-$(CONFIG_SUPERHYWAY) += superhyway/ |
| 6 | obj-$(CONFIG_MAPLE) += maple/ | 5 | obj-$(CONFIG_MAPLE) += maple/ |
| 6 | obj-y += intc.o | ||
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c new file mode 100644 index 000000000000..58d24c5a76ce --- /dev/null +++ b/drivers/sh/intc.c | |||
| @@ -0,0 +1,713 @@ | |||
| 1 | /* | ||
| 2 | * Shared interrupt handling code for IPR and INTC2 types of IRQs. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2007, 2008 Magnus Damm | ||
| 5 | * | ||
| 6 | * Based on intc2.c and ipr.c | ||
| 7 | * | ||
| 8 | * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi | ||
| 9 | * Copyright (C) 2000 Kazumoto Kojima | ||
| 10 | * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) | ||
| 11 | * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> | ||
| 12 | * Copyright (C) 2005, 2006 Paul Mundt | ||
| 13 | * | ||
| 14 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 15 | * License. See the file "COPYING" in the main directory of this archive | ||
| 16 | * for more details. | ||
| 17 | */ | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/irq.h> | ||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | #include <linux/interrupt.h> | ||
| 23 | #include <linux/bootmem.h> | ||
| 24 | #include <linux/sh_intc.h> | ||
| 25 | |||
| 26 | #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ | ||
| 27 | ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ | ||
| 28 | ((addr_e) << 16) | ((addr_d << 24))) | ||
| 29 | |||
| 30 | #define _INTC_SHIFT(h) (h & 0x1f) | ||
| 31 | #define _INTC_WIDTH(h) ((h >> 5) & 0xf) | ||
| 32 | #define _INTC_FN(h) ((h >> 9) & 0xf) | ||
| 33 | #define _INTC_MODE(h) ((h >> 13) & 0x7) | ||
| 34 | #define _INTC_ADDR_E(h) ((h >> 16) & 0xff) | ||
| 35 | #define _INTC_ADDR_D(h) ((h >> 24) & 0xff) | ||
| 36 | |||
| 37 | struct intc_handle_int { | ||
| 38 | unsigned int irq; | ||
| 39 | unsigned long handle; | ||
| 40 | }; | ||
| 41 | |||
| 42 | struct intc_desc_int { | ||
| 43 | unsigned long *reg; | ||
| 44 | #ifdef CONFIG_SMP | ||
| 45 | unsigned long *smp; | ||
| 46 | #endif | ||
| 47 | unsigned int nr_reg; | ||
| 48 | struct intc_handle_int *prio; | ||
| 49 | unsigned int nr_prio; | ||
| 50 | struct intc_handle_int *sense; | ||
| 51 | unsigned int nr_sense; | ||
| 52 | struct irq_chip chip; | ||
| 53 | }; | ||
| 54 | |||
| 55 | #ifdef CONFIG_SMP | ||
| 56 | #define IS_SMP(x) x.smp | ||
| 57 | #define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c)) | ||
| 58 | #define SMP_NR(d, x) ((d->smp[(x)] >> 8) ? (d->smp[(x)] >> 8) : 1) | ||
| 59 | #else | ||
| 60 | #define IS_SMP(x) 0 | ||
| 61 | #define INTC_REG(d, x, c) (d->reg[(x)]) | ||
| 62 | #define SMP_NR(d, x) 1 | ||
| 63 | #endif | ||
| 64 | |||
| 65 | static unsigned int intc_prio_level[NR_IRQS]; /* for now */ | ||
| 66 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) | ||
| 67 | static unsigned long ack_handle[NR_IRQS]; | ||
| 68 | #endif | ||
| 69 | |||
| 70 | static inline struct intc_desc_int *get_intc_desc(unsigned int irq) | ||
| 71 | { | ||
| 72 | struct irq_chip *chip = get_irq_chip(irq); | ||
| 73 | return (void *)((char *)chip - offsetof(struct intc_desc_int, chip)); | ||
| 74 | } | ||
| 75 | |||
| 76 | static inline unsigned int set_field(unsigned int value, | ||
| 77 | unsigned int field_value, | ||
| 78 | unsigned int handle) | ||
| 79 | { | ||
| 80 | unsigned int width = _INTC_WIDTH(handle); | ||
| 81 | unsigned int shift = _INTC_SHIFT(handle); | ||
| 82 | |||
| 83 | value &= ~(((1 << width) - 1) << shift); | ||
| 84 | value |= field_value << shift; | ||
| 85 | return value; | ||
| 86 | } | ||
| 87 | |||
| 88 | static void write_8(unsigned long addr, unsigned long h, unsigned long data) | ||
| 89 | { | ||
| 90 | __raw_writeb(set_field(0, data, h), addr); | ||
| 91 | } | ||
| 92 | |||
| 93 | static void write_16(unsigned long addr, unsigned long h, unsigned long data) | ||
| 94 | { | ||
| 95 | __raw_writew(set_field(0, data, h), addr); | ||
| 96 | } | ||
| 97 | |||
| 98 | static void write_32(unsigned long addr, unsigned long h, unsigned long data) | ||
| 99 | { | ||
| 100 | __raw_writel(set_field(0, data, h), addr); | ||
| 101 | } | ||
| 102 | |||
| 103 | static void modify_8(unsigned long addr, unsigned long h, unsigned long data) | ||
| 104 | { | ||
| 105 | unsigned long flags; | ||
| 106 | local_irq_save(flags); | ||
| 107 | __raw_writeb(set_field(__raw_readb(addr), data, h), addr); | ||
| 108 | local_irq_restore(flags); | ||
| 109 | } | ||
| 110 | |||
| 111 | static void modify_16(unsigned long addr, unsigned long h, unsigned long data) | ||
| 112 | { | ||
| 113 | unsigned long flags; | ||
| 114 | local_irq_save(flags); | ||
| 115 | __raw_writew(set_field(__raw_readw(addr), data, h), addr); | ||
| 116 | local_irq_restore(flags); | ||
| 117 | } | ||
| 118 | |||
| 119 | static void modify_32(unsigned long addr, unsigned long h, unsigned long data) | ||
| 120 | { | ||
| 121 | unsigned long flags; | ||
| 122 | local_irq_save(flags); | ||
| 123 | __raw_writel(set_field(__raw_readl(addr), data, h), addr); | ||
| 124 | local_irq_restore(flags); | ||
| 125 | } | ||
| 126 | |||
| 127 | enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 }; | ||
| 128 | |||
| 129 | static void (*intc_reg_fns[])(unsigned long addr, | ||
| 130 | unsigned long h, | ||
| 131 | unsigned long data) = { | ||
| 132 | [REG_FN_WRITE_BASE + 0] = write_8, | ||
| 133 | [REG_FN_WRITE_BASE + 1] = write_16, | ||
| 134 | [REG_FN_WRITE_BASE + 3] = write_32, | ||
| 135 | [REG_FN_MODIFY_BASE + 0] = modify_8, | ||
| 136 | [REG_FN_MODIFY_BASE + 1] = modify_16, | ||
| 137 | [REG_FN_MODIFY_BASE + 3] = modify_32, | ||
| 138 | }; | ||
| 139 | |||
| 140 | enum { MODE_ENABLE_REG = 0, /* Bit(s) set -> interrupt enabled */ | ||
| 141 | MODE_MASK_REG, /* Bit(s) set -> interrupt disabled */ | ||
| 142 | MODE_DUAL_REG, /* Two registers, set bit to enable / disable */ | ||
| 143 | MODE_PRIO_REG, /* Priority value written to enable interrupt */ | ||
| 144 | MODE_PCLR_REG, /* Above plus all bits set to disable interrupt */ | ||
| 145 | }; | ||
| 146 | |||
| 147 | static void intc_mode_field(unsigned long addr, | ||
| 148 | unsigned long handle, | ||
| 149 | void (*fn)(unsigned long, | ||
| 150 | unsigned long, | ||
| 151 | unsigned long), | ||
| 152 | unsigned int irq) | ||
| 153 | { | ||
| 154 | fn(addr, handle, ((1 << _INTC_WIDTH(handle)) - 1)); | ||
| 155 | } | ||
| 156 | |||
| 157 | static void intc_mode_zero(unsigned long addr, | ||
| 158 | unsigned long handle, | ||
| 159 | void (*fn)(unsigned long, | ||
| 160 | unsigned long, | ||
| 161 | unsigned long), | ||
| 162 | unsigned int irq) | ||
| 163 | { | ||
| 164 | fn(addr, handle, 0); | ||
| 165 | } | ||
| 166 | |||
| 167 | static void intc_mode_prio(unsigned long addr, | ||
| 168 | unsigned long handle, | ||
| 169 | void (*fn)(unsigned long, | ||
| 170 | unsigned long, | ||
| 171 | unsigned long), | ||
| 172 | unsigned int irq) | ||
| 173 | { | ||
| 174 | fn(addr, handle, intc_prio_level[irq]); | ||
| 175 | } | ||
| 176 | |||
| 177 | static void (*intc_enable_fns[])(unsigned long addr, | ||
| 178 | unsigned long handle, | ||
| 179 | void (*fn)(unsigned long, | ||
| 180 | unsigned long, | ||
| 181 | unsigned long), | ||
| 182 | unsigned int irq) = { | ||
| 183 | [MODE_ENABLE_REG] = intc_mode_field, | ||
| 184 | [MODE_MASK_REG] = intc_mode_zero, | ||
| 185 | [MODE_DUAL_REG] = intc_mode_field, | ||
| 186 | [MODE_PRIO_REG] = intc_mode_prio, | ||
| 187 | [MODE_PCLR_REG] = intc_mode_prio, | ||
| 188 | }; | ||
| 189 | |||
| 190 | static void (*intc_disable_fns[])(unsigned long addr, | ||
| 191 | unsigned long handle, | ||
| 192 | void (*fn)(unsigned long, | ||
| 193 | unsigned long, | ||
| 194 | unsigned long), | ||
| 195 | unsigned int irq) = { | ||
| 196 | [MODE_ENABLE_REG] = intc_mode_zero, | ||
| 197 | [MODE_MASK_REG] = intc_mode_field, | ||
| 198 | [MODE_DUAL_REG] = intc_mode_field, | ||
| 199 | [MODE_PRIO_REG] = intc_mode_zero, | ||
| 200 | [MODE_PCLR_REG] = intc_mode_field, | ||
| 201 | }; | ||
| 202 | |||
| 203 | static inline void _intc_enable(unsigned int irq, unsigned long handle) | ||
| 204 | { | ||
| 205 | struct intc_desc_int *d = get_intc_desc(irq); | ||
| 206 | unsigned long addr; | ||
| 207 | unsigned int cpu; | ||
| 208 | |||
| 209 | for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) { | ||
| 210 | addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu); | ||
| 211 | intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\ | ||
| 212 | [_INTC_FN(handle)], irq); | ||
| 213 | } | ||
| 214 | } | ||
| 215 | |||
| 216 | static void intc_enable(unsigned int irq) | ||
| 217 | { | ||
| 218 | _intc_enable(irq, (unsigned long)get_irq_chip_data(irq)); | ||
| 219 | } | ||
| 220 | |||
| 221 | static void intc_disable(unsigned int irq) | ||
| 222 | { | ||
| 223 | struct intc_desc_int *d = get_intc_desc(irq); | ||
| 224 | unsigned long handle = (unsigned long) get_irq_chip_data(irq); | ||
| 225 | unsigned long addr; | ||
| 226 | unsigned int cpu; | ||
| 227 | |||
| 228 | for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { | ||
| 229 | addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu); | ||
| 230 | intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\ | ||
| 231 | [_INTC_FN(handle)], irq); | ||
| 232 | } | ||
| 233 | } | ||
| 234 | |||
| 235 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) | ||
| 236 | static void intc_mask_ack(unsigned int irq) | ||
| 237 | { | ||
| 238 | struct intc_desc_int *d = get_intc_desc(irq); | ||
| 239 | unsigned long handle = ack_handle[irq]; | ||
| 240 | unsigned long addr; | ||
| 241 | |||
| 242 | intc_disable(irq); | ||
| 243 | |||
| 244 | /* read register and write zero only to the assocaited bit */ | ||
| 245 | |||
| 246 | if (handle) { | ||
| 247 | addr = INTC_REG(d, _INTC_ADDR_D(handle), 0); | ||
| 248 | switch (_INTC_FN(handle)) { | ||
| 249 | case REG_FN_MODIFY_BASE + 0: /* 8bit */ | ||
| 250 | __raw_readb(addr); | ||
| 251 | __raw_writeb(0xff ^ set_field(0, 1, handle), addr); | ||
| 252 | break; | ||
| 253 | case REG_FN_MODIFY_BASE + 1: /* 16bit */ | ||
| 254 | __raw_readw(addr); | ||
| 255 | __raw_writew(0xffff ^ set_field(0, 1, handle), addr); | ||
| 256 | break; | ||
| 257 | case REG_FN_MODIFY_BASE + 3: /* 32bit */ | ||
| 258 | __raw_readl(addr); | ||
| 259 | __raw_writel(0xffffffff ^ set_field(0, 1, handle), addr); | ||
| 260 | break; | ||
| 261 | default: | ||
| 262 | BUG(); | ||
| 263 | break; | ||
| 264 | } | ||
| 265 | } | ||
| 266 | } | ||
| 267 | #endif | ||
| 268 | |||
| 269 | static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp, | ||
| 270 | unsigned int nr_hp, | ||
| 271 | unsigned int irq) | ||
| 272 | { | ||
| 273 | int i; | ||
| 274 | |||
| 275 | /* this doesn't scale well, but... | ||
| 276 | * | ||
| 277 | * this function should only be used for cerain uncommon | ||
| 278 | * operations such as intc_set_priority() and intc_set_sense() | ||
| 279 | * and in those rare cases performance doesn't matter that much. | ||
| 280 | * keeping the memory footprint low is more important. | ||
| 281 | * | ||
| 282 | * one rather simple way to speed this up and still keep the | ||
| 283 | * memory footprint down is to make sure the array is sorted | ||
| 284 | * and then perform a bisect to lookup the irq. | ||
| 285 | */ | ||
| 286 | |||
| 287 | for (i = 0; i < nr_hp; i++) { | ||
| 288 | if ((hp + i)->irq != irq) | ||
| 289 | continue; | ||
| 290 | |||
| 291 | return hp + i; | ||
| 292 | } | ||
| 293 | |||
| 294 | return NULL; | ||
| 295 | } | ||
| 296 | |||
| 297 | int intc_set_priority(unsigned int irq, unsigned int prio) | ||
| 298 | { | ||
| 299 | struct intc_desc_int *d = get_intc_desc(irq); | ||
| 300 | struct intc_handle_int *ihp; | ||
| 301 | |||
| 302 | if (!intc_prio_level[irq] || prio <= 1) | ||
| 303 | return -EINVAL; | ||
| 304 | |||
| 305 | ihp = intc_find_irq(d->prio, d->nr_prio, irq); | ||
| 306 | if (ihp) { | ||
| 307 | if (prio >= (1 << _INTC_WIDTH(ihp->handle))) | ||
| 308 | return -EINVAL; | ||
| 309 | |||
| 310 | intc_prio_level[irq] = prio; | ||
| 311 | |||
| 312 | /* | ||
| 313 | * only set secondary masking method directly | ||
| 314 | * primary masking method is using intc_prio_level[irq] | ||
| 315 | * priority level will be set during next enable() | ||
| 316 | */ | ||
| 317 | |||
| 318 | if (_INTC_FN(ihp->handle) != REG_FN_ERR) | ||
| 319 | _intc_enable(irq, ihp->handle); | ||
| 320 | } | ||
| 321 | return 0; | ||
| 322 | } | ||
| 323 | |||
| 324 | #define VALID(x) (x | 0x80) | ||
| 325 | |||
| 326 | static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { | ||
| 327 | [IRQ_TYPE_EDGE_FALLING] = VALID(0), | ||
| 328 | [IRQ_TYPE_EDGE_RISING] = VALID(1), | ||
| 329 | [IRQ_TYPE_LEVEL_LOW] = VALID(2), | ||
| 330 | /* SH7706, SH7707 and SH7709 do not support high level triggered */ | ||
| 331 | #if !defined(CONFIG_CPU_SUBTYPE_SH7706) && \ | ||
| 332 | !defined(CONFIG_CPU_SUBTYPE_SH7707) && \ | ||
| 333 | !defined(CONFIG_CPU_SUBTYPE_SH7709) | ||
| 334 | [IRQ_TYPE_LEVEL_HIGH] = VALID(3), | ||
| 335 | #endif | ||
| 336 | }; | ||
| 337 | |||
| 338 | static int intc_set_sense(unsigned int irq, unsigned int type) | ||
| 339 | { | ||
| 340 | struct intc_desc_int *d = get_intc_desc(irq); | ||
| 341 | unsigned char value = intc_irq_sense_table[type & IRQ_TYPE_SENSE_MASK]; | ||
| 342 | struct intc_handle_int *ihp; | ||
| 343 | unsigned long addr; | ||
| 344 | |||
| 345 | if (!value) | ||
| 346 | return -EINVAL; | ||
| 347 | |||
| 348 | ihp = intc_find_irq(d->sense, d->nr_sense, irq); | ||
| 349 | if (ihp) { | ||
| 350 | addr = INTC_REG(d, _INTC_ADDR_E(ihp->handle), 0); | ||
| 351 | intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle, value); | ||
| 352 | } | ||
| 353 | return 0; | ||
| 354 | } | ||
| 355 | |||
| 356 | static unsigned int __init intc_get_reg(struct intc_desc_int *d, | ||
| 357 | unsigned long address) | ||
| 358 | { | ||
| 359 | unsigned int k; | ||
| 360 | |||
| 361 | for (k = 0; k < d->nr_reg; k++) { | ||
| 362 | if (d->reg[k] == address) | ||
| 363 | return k; | ||
| 364 | } | ||
| 365 | |||
| 366 | BUG(); | ||
| 367 | return 0; | ||
| 368 | } | ||
| 369 | |||
| 370 | static intc_enum __init intc_grp_id(struct intc_desc *desc, | ||
| 371 | intc_enum enum_id) | ||
| 372 | { | ||
| 373 | struct intc_group *g = desc->groups; | ||
| 374 | unsigned int i, j; | ||
| 375 | |||
| 376 | for (i = 0; g && enum_id && i < desc->nr_groups; i++) { | ||
| 377 | g = desc->groups + i; | ||
| 378 | |||
| 379 | for (j = 0; g->enum_ids[j]; j++) { | ||
| 380 | if (g->enum_ids[j] != enum_id) | ||
| 381 | continue; | ||
| 382 | |||
| 383 | return g->enum_id; | ||
| 384 | } | ||
| 385 | } | ||
| 386 | |||
| 387 | return 0; | ||
| 388 | } | ||
| 389 | |||
| 390 | static unsigned int __init intc_mask_data(struct intc_desc *desc, | ||
| 391 | struct intc_desc_int *d, | ||
| 392 | intc_enum enum_id, int do_grps) | ||
| 393 | { | ||
| 394 | struct intc_mask_reg *mr = desc->mask_regs; | ||
| 395 | unsigned int i, j, fn, mode; | ||
| 396 | unsigned long reg_e, reg_d; | ||
| 397 | |||
| 398 | for (i = 0; mr && enum_id && i < desc->nr_mask_regs; i++) { | ||
| 399 | mr = desc->mask_regs + i; | ||
| 400 | |||
| 401 | for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) { | ||
| 402 | if (mr->enum_ids[j] != enum_id) | ||
| 403 | continue; | ||
| 404 | |||
| 405 | if (mr->set_reg && mr->clr_reg) { | ||
| 406 | fn = REG_FN_WRITE_BASE; | ||
| 407 | mode = MODE_DUAL_REG; | ||
| 408 | reg_e = mr->clr_reg; | ||
| 409 | reg_d = mr->set_reg; | ||
| 410 | } else { | ||
| 411 | fn = REG_FN_MODIFY_BASE; | ||
| 412 | if (mr->set_reg) { | ||
| 413 | mode = MODE_ENABLE_REG; | ||
| 414 | reg_e = mr->set_reg; | ||
| 415 | reg_d = mr->set_reg; | ||
| 416 | } else { | ||
| 417 | mode = MODE_MASK_REG; | ||
| 418 | reg_e = mr->clr_reg; | ||
| 419 | reg_d = mr->clr_reg; | ||
| 420 | } | ||
| 421 | } | ||
| 422 | |||
| 423 | fn += (mr->reg_width >> 3) - 1; | ||
| 424 | return _INTC_MK(fn, mode, | ||
| 425 | intc_get_reg(d, reg_e), | ||
| 426 | intc_get_reg(d, reg_d), | ||
| 427 | 1, | ||
| 428 | (mr->reg_width - 1) - j); | ||
| 429 | } | ||
| 430 | } | ||
| 431 | |||
| 432 | if (do_grps) | ||
| 433 | return intc_mask_data(desc, d, intc_grp_id(desc, enum_id), 0); | ||
| 434 | |||
| 435 | return 0; | ||
| 436 | } | ||
| 437 | |||
| 438 | static unsigned int __init intc_prio_data(struct intc_desc *desc, | ||
| 439 | struct intc_desc_int *d, | ||
| 440 | intc_enum enum_id, int do_grps) | ||
| 441 | { | ||
| 442 | struct intc_prio_reg *pr = desc->prio_regs; | ||
| 443 | unsigned int i, j, fn, mode, bit; | ||
| 444 | unsigned long reg_e, reg_d; | ||
| 445 | |||
| 446 | for (i = 0; pr && enum_id && i < desc->nr_prio_regs; i++) { | ||
| 447 | pr = desc->prio_regs + i; | ||
| 448 | |||
| 449 | for (j = 0; j < ARRAY_SIZE(pr->enum_ids); j++) { | ||
| 450 | if (pr->enum_ids[j] != enum_id) | ||
| 451 | continue; | ||
| 452 | |||
| 453 | if (pr->set_reg && pr->clr_reg) { | ||
| 454 | fn = REG_FN_WRITE_BASE; | ||
| 455 | mode = MODE_PCLR_REG; | ||
| 456 | reg_e = pr->set_reg; | ||
| 457 | reg_d = pr->clr_reg; | ||
| 458 | } else { | ||
| 459 | fn = REG_FN_MODIFY_BASE; | ||
| 460 | mode = MODE_PRIO_REG; | ||
| 461 | if (!pr->set_reg) | ||
| 462 | BUG(); | ||
| 463 | reg_e = pr->set_reg; | ||
| 464 | reg_d = pr->set_reg; | ||
| 465 | } | ||
| 466 | |||
| 467 | fn += (pr->reg_width >> 3) - 1; | ||
| 468 | |||
| 469 | BUG_ON((j + 1) * pr->field_width > pr->reg_width); | ||
| 470 | |||
| 471 | bit = pr->reg_width - ((j + 1) * pr->field_width); | ||
| 472 | |||
| 473 | return _INTC_MK(fn, mode, | ||
| 474 | intc_get_reg(d, reg_e), | ||
| 475 | intc_get_reg(d, reg_d), | ||
| 476 | pr->field_width, bit); | ||
| 477 | } | ||
| 478 | } | ||
| 479 | |||
| 480 | if (do_grps) | ||
| 481 | return intc_prio_data(desc, d, intc_grp_id(desc, enum_id), 0); | ||
| 482 | |||
| 483 | return 0; | ||
| 484 | } | ||
| 485 | |||
| 486 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) | ||
| 487 | static unsigned int __init intc_ack_data(struct intc_desc *desc, | ||
| 488 | struct intc_desc_int *d, | ||
| 489 | intc_enum enum_id) | ||
| 490 | { | ||
| 491 | struct intc_mask_reg *mr = desc->ack_regs; | ||
| 492 | unsigned int i, j, fn, mode; | ||
| 493 | unsigned long reg_e, reg_d; | ||
| 494 | |||
| 495 | for (i = 0; mr && enum_id && i < desc->nr_ack_regs; i++) { | ||
| 496 | mr = desc->ack_regs + i; | ||
| 497 | |||
| 498 | for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) { | ||
| 499 | if (mr->enum_ids[j] != enum_id) | ||
| 500 | continue; | ||
| 501 | |||
| 502 | fn = REG_FN_MODIFY_BASE; | ||
| 503 | mode = MODE_ENABLE_REG; | ||
| 504 | reg_e = mr->set_reg; | ||
| 505 | reg_d = mr->set_reg; | ||
| 506 | |||
| 507 | fn += (mr->reg_width >> 3) - 1; | ||
| 508 | return _INTC_MK(fn, mode, | ||
| 509 | intc_get_reg(d, reg_e), | ||
| 510 | intc_get_reg(d, reg_d), | ||
| 511 | 1, | ||
| 512 | (mr->reg_width - 1) - j); | ||
| 513 | } | ||
| 514 | } | ||
| 515 | |||
| 516 | return 0; | ||
| 517 | } | ||
| 518 | #endif | ||
| 519 | |||
| 520 | static unsigned int __init intc_sense_data(struct intc_desc *desc, | ||
| 521 | struct intc_desc_int *d, | ||
| 522 | intc_enum enum_id) | ||
| 523 | { | ||
| 524 | struct intc_sense_reg *sr = desc->sense_regs; | ||
| 525 | unsigned int i, j, fn, bit; | ||
| 526 | |||
| 527 | for (i = 0; sr && enum_id && i < desc->nr_sense_regs; i++) { | ||
| 528 | sr = desc->sense_regs + i; | ||
| 529 | |||
| 530 | for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) { | ||
| 531 | if (sr->enum_ids[j] != enum_id) | ||
| 532 | continue; | ||
| 533 | |||
| 534 | fn = REG_FN_MODIFY_BASE; | ||
| 535 | fn += (sr->reg_width >> 3) - 1; | ||
| 536 | |||
| 537 | BUG_ON((j + 1) * sr->field_width > sr->reg_width); | ||
| 538 | |||
| 539 | bit = sr->reg_width - ((j + 1) * sr->field_width); | ||
| 540 | |||
| 541 | return _INTC_MK(fn, 0, intc_get_reg(d, sr->reg), | ||
| 542 | 0, sr->field_width, bit); | ||
| 543 | } | ||
| 544 | } | ||
| 545 | |||
| 546 | return 0; | ||
| 547 | } | ||
| 548 | |||
| 549 | static void __init intc_register_irq(struct intc_desc *desc, | ||
| 550 | struct intc_desc_int *d, | ||
| 551 | intc_enum enum_id, | ||
| 552 | unsigned int irq) | ||
| 553 | { | ||
| 554 | struct intc_handle_int *hp; | ||
| 555 | unsigned int data[2], primary; | ||
| 556 | |||
| 557 | /* Prefer single interrupt source bitmap over other combinations: | ||
| 558 | * 1. bitmap, single interrupt source | ||
| 559 | * 2. priority, single interrupt source | ||
| 560 | * 3. bitmap, multiple interrupt sources (groups) | ||
| 561 | * 4. priority, multiple interrupt sources (groups) | ||
| 562 | */ | ||
| 563 | |||
| 564 | data[0] = intc_mask_data(desc, d, enum_id, 0); | ||
| 565 | data[1] = intc_prio_data(desc, d, enum_id, 0); | ||
| 566 | |||
| 567 | primary = 0; | ||
| 568 | if (!data[0] && data[1]) | ||
| 569 | primary = 1; | ||
| 570 | |||
| 571 | data[0] = data[0] ? data[0] : intc_mask_data(desc, d, enum_id, 1); | ||
| 572 | data[1] = data[1] ? data[1] : intc_prio_data(desc, d, enum_id, 1); | ||
| 573 | |||
| 574 | if (!data[primary]) | ||
| 575 | primary ^= 1; | ||
| 576 | |||
| 577 | BUG_ON(!data[primary]); /* must have primary masking method */ | ||
| 578 | |||
| 579 | disable_irq_nosync(irq); | ||
| 580 | set_irq_chip_and_handler_name(irq, &d->chip, | ||
| 581 | handle_level_irq, "level"); | ||
| 582 | set_irq_chip_data(irq, (void *)data[primary]); | ||
| 583 | |||
| 584 | /* set priority level | ||
| 585 | * - this needs to be at least 2 for 5-bit priorities on 7780 | ||
| 586 | */ | ||
| 587 | intc_prio_level[irq] = 2; | ||
| 588 | |||
| 589 | /* enable secondary masking method if present */ | ||
| 590 | if (data[!primary]) | ||
| 591 | _intc_enable(irq, data[!primary]); | ||
| 592 | |||
| 593 | /* add irq to d->prio list if priority is available */ | ||
| 594 | if (data[1]) { | ||
| 595 | hp = d->prio + d->nr_prio; | ||
| 596 | hp->irq = irq; | ||
| 597 | hp->handle = data[1]; | ||
| 598 | |||
| 599 | if (primary) { | ||
| 600 | /* | ||
| 601 | * only secondary priority should access registers, so | ||
| 602 | * set _INTC_FN(h) = REG_FN_ERR for intc_set_priority() | ||
| 603 | */ | ||
| 604 | |||
| 605 | hp->handle &= ~_INTC_MK(0x0f, 0, 0, 0, 0, 0); | ||
| 606 | hp->handle |= _INTC_MK(REG_FN_ERR, 0, 0, 0, 0, 0); | ||
| 607 | } | ||
| 608 | d->nr_prio++; | ||
| 609 | } | ||
| 610 | |||
| 611 | /* add irq to d->sense list if sense is available */ | ||
| 612 | data[0] = intc_sense_data(desc, d, enum_id); | ||
| 613 | if (data[0]) { | ||
| 614 | (d->sense + d->nr_sense)->irq = irq; | ||
| 615 | (d->sense + d->nr_sense)->handle = data[0]; | ||
| 616 | d->nr_sense++; | ||
| 617 | } | ||
| 618 | |||
| 619 | /* irq should be disabled by default */ | ||
| 620 | d->chip.mask(irq); | ||
| 621 | |||
| 622 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) | ||
| 623 | if (desc->ack_regs) | ||
| 624 | ack_handle[irq] = intc_ack_data(desc, d, enum_id); | ||
| 625 | #endif | ||
| 626 | } | ||
| 627 | |||
| 628 | static unsigned int __init save_reg(struct intc_desc_int *d, | ||
| 629 | unsigned int cnt, | ||
| 630 | unsigned long value, | ||
| 631 | unsigned int smp) | ||
| 632 | { | ||
| 633 | if (value) { | ||
| 634 | d->reg[cnt] = value; | ||
| 635 | #ifdef CONFIG_SMP | ||
| 636 | d->smp[cnt] = smp; | ||
| 637 | #endif | ||
| 638 | return 1; | ||
| 639 | } | ||
| 640 | |||
| 641 | return 0; | ||
| 642 | } | ||
| 643 | |||
| 644 | |||
| 645 | void __init register_intc_controller(struct intc_desc *desc) | ||
| 646 | { | ||
| 647 | unsigned int i, k, smp; | ||
| 648 | struct intc_desc_int *d; | ||
| 649 | |||
| 650 | d = alloc_bootmem(sizeof(*d)); | ||
| 651 | |||
| 652 | d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0; | ||
| 653 | d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0; | ||
| 654 | d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0; | ||
| 655 | |||
| 656 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) | ||
| 657 | d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0; | ||
| 658 | #endif | ||
| 659 | d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg)); | ||
| 660 | #ifdef CONFIG_SMP | ||
| 661 | d->smp = alloc_bootmem(d->nr_reg * sizeof(*d->smp)); | ||
| 662 | #endif | ||
| 663 | k = 0; | ||
| 664 | |||
| 665 | if (desc->mask_regs) { | ||
| 666 | for (i = 0; i < desc->nr_mask_regs; i++) { | ||
| 667 | smp = IS_SMP(desc->mask_regs[i]); | ||
| 668 | k += save_reg(d, k, desc->mask_regs[i].set_reg, smp); | ||
| 669 | k += save_reg(d, k, desc->mask_regs[i].clr_reg, smp); | ||
| 670 | } | ||
| 671 | } | ||
| 672 | |||
| 673 | if (desc->prio_regs) { | ||
| 674 | d->prio = alloc_bootmem(desc->nr_vectors * sizeof(*d->prio)); | ||
| 675 | |||
| 676 | for (i = 0; i < desc->nr_prio_regs; i++) { | ||
| 677 | smp = IS_SMP(desc->prio_regs[i]); | ||
| 678 | k += save_reg(d, k, desc->prio_regs[i].set_reg, smp); | ||
| 679 | k += save_reg(d, k, desc->prio_regs[i].clr_reg, smp); | ||
| 680 | } | ||
| 681 | } | ||
| 682 | |||
| 683 | if (desc->sense_regs) { | ||
| 684 | d->sense = alloc_bootmem(desc->nr_vectors * sizeof(*d->sense)); | ||
| 685 | |||
| 686 | for (i = 0; i < desc->nr_sense_regs; i++) { | ||
| 687 | k += save_reg(d, k, desc->sense_regs[i].reg, 0); | ||
| 688 | } | ||
| 689 | } | ||
| 690 | |||
| 691 | d->chip.name = desc->name; | ||
| 692 | d->chip.mask = intc_disable; | ||
| 693 | d->chip.unmask = intc_enable; | ||
| 694 | d->chip.mask_ack = intc_disable; | ||
| 695 | d->chip.set_type = intc_set_sense; | ||
| 696 | |||
| 697 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) | ||
| 698 | if (desc->ack_regs) { | ||
| 699 | for (i = 0; i < desc->nr_ack_regs; i++) | ||
| 700 | k += save_reg(d, k, desc->ack_regs[i].set_reg, 0); | ||
| 701 | |||
| 702 | d->chip.mask_ack = intc_mask_ack; | ||
| 703 | } | ||
| 704 | #endif | ||
| 705 | |||
| 706 | BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ | ||
| 707 | |||
| 708 | for (i = 0; i < desc->nr_vectors; i++) { | ||
| 709 | struct intc_vect *vect = desc->vectors + i; | ||
| 710 | |||
| 711 | intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect)); | ||
| 712 | } | ||
| 713 | } | ||
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index 6fa0b9d5559a..d4cfed0b26d5 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | #include <linux/backlight.h> | 19 | #include <linux/backlight.h> |
| 20 | 20 | ||
| 21 | #include <cpu/dac.h> | 21 | #include <cpu/dac.h> |
| 22 | #include <asm/hp6xx.h> | 22 | #include <mach/hp6xx.h> |
| 23 | #include <asm/hd64461.h> | 23 | #include <asm/hd64461.h> |
| 24 | 24 | ||
| 25 | #define HP680_MAX_INTENSITY 255 | 25 | #define HP680_MAX_INTENSITY 255 |
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 4c32c06579a0..efff672fd7b8 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
| 17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 18 | #include <linux/dma-mapping.h> | 18 | #include <linux/dma-mapping.h> |
| 19 | #include <asm/sh_mobile_lcdc.h> | 19 | #include <video/sh_mobile_lcdc.h> |
| 20 | 20 | ||
| 21 | #define PALETTE_NR 16 | 21 | #define PALETTE_NR 16 |
| 22 | 22 | ||
| @@ -34,7 +34,9 @@ struct sh_mobile_lcdc_chan { | |||
| 34 | 34 | ||
| 35 | struct sh_mobile_lcdc_priv { | 35 | struct sh_mobile_lcdc_priv { |
| 36 | void __iomem *base; | 36 | void __iomem *base; |
| 37 | #ifdef CONFIG_HAVE_CLK | ||
| 37 | struct clk *clk; | 38 | struct clk *clk; |
| 39 | #endif | ||
| 38 | unsigned long lddckr; | 40 | unsigned long lddckr; |
| 39 | struct sh_mobile_lcdc_chan ch[2]; | 41 | struct sh_mobile_lcdc_chan ch[2]; |
| 40 | }; | 42 | }; |
| @@ -260,6 +262,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
| 260 | tmp = ch->ldmt1r_value; | 262 | tmp = ch->ldmt1r_value; |
| 261 | tmp |= (lcd_cfg->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1 << 28; | 263 | tmp |= (lcd_cfg->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1 << 28; |
| 262 | tmp |= (lcd_cfg->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1 << 27; | 264 | tmp |= (lcd_cfg->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1 << 27; |
| 265 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DWPOL) ? 1 << 26 : 0; | ||
| 266 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DIPOL) ? 1 << 25 : 0; | ||
| 267 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DAPOL) ? 1 << 24 : 0; | ||
| 268 | tmp |= (ch->cfg.flags & LCDC_FLAGS_HSCNT) ? 1 << 17 : 0; | ||
| 269 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DWCNT) ? 1 << 16 : 0; | ||
| 263 | lcdc_write_chan(ch, LDMT1R, tmp); | 270 | lcdc_write_chan(ch, LDMT1R, tmp); |
| 264 | 271 | ||
| 265 | /* setup SYS bus */ | 272 | /* setup SYS bus */ |
| @@ -422,6 +429,7 @@ static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source, | |||
| 422 | 429 | ||
| 423 | priv->lddckr = icksel << 16; | 430 | priv->lddckr = icksel << 16; |
| 424 | 431 | ||
| 432 | #ifdef CONFIG_HAVE_CLK | ||
| 425 | if (str) { | 433 | if (str) { |
| 426 | priv->clk = clk_get(dev, str); | 434 | priv->clk = clk_get(dev, str); |
| 427 | if (IS_ERR(priv->clk)) { | 435 | if (IS_ERR(priv->clk)) { |
| @@ -431,6 +439,7 @@ static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source, | |||
| 431 | 439 | ||
| 432 | clk_enable(priv->clk); | 440 | clk_enable(priv->clk); |
| 433 | } | 441 | } |
| 442 | #endif | ||
| 434 | 443 | ||
| 435 | return 0; | 444 | return 0; |
| 436 | } | 445 | } |
| @@ -585,7 +594,6 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
| 585 | goto err1; | 594 | goto err1; |
| 586 | } | 595 | } |
| 587 | 596 | ||
| 588 | priv->lddckr = pdata->lddckr; | ||
| 589 | priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1); | 597 | priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1); |
| 590 | 598 | ||
| 591 | for (i = 0; i < j; i++) { | 599 | for (i = 0; i < j; i++) { |
| @@ -688,10 +696,12 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) | |||
| 688 | fb_dealloc_cmap(&info->cmap); | 696 | fb_dealloc_cmap(&info->cmap); |
| 689 | } | 697 | } |
| 690 | 698 | ||
| 699 | #ifdef CONFIG_HAVE_CLK | ||
| 691 | if (priv->clk) { | 700 | if (priv->clk) { |
| 692 | clk_disable(priv->clk); | 701 | clk_disable(priv->clk); |
| 693 | clk_put(priv->clk); | 702 | clk_put(priv->clk); |
| 694 | } | 703 | } |
| 704 | #endif | ||
| 695 | 705 | ||
| 696 | if (priv->base) | 706 | if (priv->base) |
| 697 | iounmap(priv->base); | 707 | iounmap(priv->base); |
