Commit dfc1ebe7 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Device tree conversions for samsung and tegra

Both platforms had some initial device tree support, but this adds
much more to actually make it usable.

* tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (45 commits)
  ARM: dts: Add intial dts file for EXYNOS4210 SoC, SMDKV310 and ORIGEN
  ARM: EXYNOS: Add Exynos4 device tree enabled board file
  rtc: rtc-s3c: Add device tree support
  input: samsung-keypad: Add device tree support
  ARM: S5PV210: Modify platform data for pl330 driver
  ARM: S5PC100: Modify platform data for pl330 driver
  ARM: S5P64x0: Modify platform data for pl330 driver
  ARM: EXYNOS: Add a alias for pdma clocks
  ARM: EXYNOS: Limit usage of pl330 device instance to non-dt build
  ARM: SAMSUNG: Add device tree support for pl330 dma engine wrappers
  DMA: PL330: Add device tree support
  ARM: EXYNOS: Modify platform data for pl330 driver
  DMA: PL330: Infer transfer direction from transfer request instead of platform data
  DMA: PL330: move filter function into driver
  serial: samsung: Fix build for non-Exynos4210 devices
  serial: samsung: add device tree support
  serial: samsung: merge probe() function from all SoC specific extensions
  serial: samsung: merge all SoC specific port reset functions
  ARM: SAMSUNG: register uart clocks to clock lookup list
  serial: samsung: remove all uses of get_clksrc and set_clksrc
  ...

Fix up fairly trivial conflicts in arch/arm/mach-s3c2440/clock.c and
drivers/tty/serial/Kconfig both due to just adding code close to
changes.
parents acc952c1 b001befe
* Insignal's Exynos4210 based Origen evaluation board
Origen low-cost evaluation board is based on Samsung's Exynos4210 SoC.
Required root node properties:
- compatible = should be one or more of the following.
(a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board.
(b) "samsung,exynos4210" - for boards based on Exynos4210 SoC.
* Samsung's Exynos4210 based SMDKV310 evaluation board
SMDKV310 evaluation board is based on Samsung's Exynos4210 SoC.
Required root node properties:
- compatible = should be one or more of the following.
(a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board.
(b) "samsung,exynos4210" - for boards based on Exynos4210 SoC.
NVIDIA Tegra device tree bindings
-------------------------------------------
Boards with the tegra20 SoC shall have the following properties:
Required root node property:
compatible = "nvidia,tegra20";
Boards with the tegra30 SoC shall have the following properties:
Required root node property:
compatible = "nvidia,tegra30";
* ARM PrimeCell PL330 DMA Controller
The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
between memory and peripherals or memory to memory.
Required properties:
- compatible: should include both "arm,pl330" and "arm,primecell".
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: interrupt number to the cpu.
Example:
pdma0: pdma@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <99>;
};
Client drivers (device nodes requiring dma transfers from dev-to-mem or
mem-to-dev) should specify the DMA channel numbers using a two-value pair
as shown below.
[property name] = <[phandle of the dma controller] [dma request id]>;
where 'dma request id' is the dma request number which is connected
to the client controller. The 'property name' is recommended to be
of the form <name>-dma-channel.
Example: tx-dma-channel = <&pdma0 12>;
Samsung Exynos4 GPIO Controller
Required properties:
- compatible: Compatible property value should be "samsung,exynos4-gpio>".
- reg: Physical base address of the controller and length of memory mapped
region.
- #gpio-cells: Should be 4. The syntax of the gpio specifier used by client nodes
should be the following with values derived from the SoC user manual.
<[phandle of the gpio controller node]
[pin number within the gpio controller]
[mux function]
[pull up/down]
[drive strength]>
Values for gpio specifier:
- Pin number: is a value between 0 to 7.
- Pull Up/Down: 0 - Pull Up/Down Disabled.
1 - Pull Down Enabled.
3 - Pull Up Enabled.
- Drive Strength: 0 - 1x,
1 - 3x,
2 - 2x,
3 - 4x
- gpio-controller: Specifies that the node is a gpio controller.
- #address-cells: should be 1.
- #size-cells: should be 1.
Example:
gpa0: gpio-controller@11400000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "samsung,exynos4-gpio";
reg = <0x11400000 0x20>;
#gpio-cells = <4>;
gpio-controller;
};
* Samsung's Keypad Controller device tree bindings
Samsung's Keypad controller is used to interface a SoC with a matrix-type
keypad device. The keypad controller supports multiple row and column lines.
A key can be placed at each intersection of a unique row and a unique column.
The keypad controller can sense a key-press and key-release and report the
event using a interrupt to the cpu.
Required SoC Specific Properties:
- compatible: should be one of the following
- "samsung,s3c6410-keypad": For controllers compatible with s3c6410 keypad
controller.
- "samsung,s5pv210-keypad": For controllers compatible with s5pv210 keypad
controller.
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: The interrupt number to the cpu.
Required Board Specific Properties:
- samsung,keypad-num-rows: Number of row lines connected to the keypad
controller.
- samsung,keypad-num-columns: Number of column lines connected to the
keypad controller.
- row-gpios: List of gpios used as row lines. The gpio specifier for
this property depends on the gpio controller to which these row lines
are connected.
- col-gpios: List of gpios used as column lines. The gpio specifier for
this property depends on the gpio controller to which these column
lines are connected.
- Keys represented as child nodes: Each key connected to the keypad
controller is represented as a child node to the keypad controller
device node and should include the following properties.
- keypad,row: the row number to which the key is connected.
- keypad,column: the column number to which the key is connected.
- linux,code: the key-code to be reported when the key is pressed
and released.
Optional Properties specific to linux:
- linux,keypad-no-autorepeat: do no enable autorepeat feature.
- linux,keypad-wakeup: use any event on keypad as wakeup event.
Example:
keypad@100A0000 {
compatible = "samsung,s5pv210-keypad";
reg = <0x100A0000 0x100>;
interrupts = <173>;
samsung,keypad-num-rows = <2>;
samsung,keypad-num-columns = <8>;
linux,input-no-autorepeat;
linux,input-wakeup;
row-gpios = <&gpx2 0 3 3 0
&gpx2 1 3 3 0>;
col-gpios = <&gpx1 0 3 0 0
&gpx1 1 3 0 0
&gpx1 2 3 0 0
&gpx1 3 3 0 0
&gpx1 4 3 0 0
&gpx1 5 3 0 0
&gpx1 6 3 0 0
&gpx1 7 3 0 0>;
key_1 {
keypad,row = <0>;
keypad,column = <3>;
linux,code = <2>;
};
key_2 {
keypad,row = <0>;
keypad,column = <4>;
linux,code = <3>;
};
key_3 {
keypad,row = <0>;
keypad,column = <5>;
linux,code = <4>;
};
};
* Samsung's S3C Real Time Clock controller
Required properties:
- compatible: should be one of the following.
* "samsung,s3c2410-rtc" - for controllers compatible with s3c2410 rtc.
* "samsung,s3c6410-rtc" - for controllers compatible with s3c6410 rtc.
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: Two interrupt numbers to the cpu should be specified. First
interrupt number is the rtc alarm interupt and second interrupt number
is the rtc tick interrupt. The number of cells representing a interrupt
depends on the parent interrupt controller.
Example:
rtc@10070000 {
compatible = "samsung,s3c6410-rtc";
reg = <0x10070000 0x100>;
interrupts = <44 0 45 0>;
};
* Samsung's UART Controller
The Samsung's UART controller is used for interfacing SoC with serial communicaion
devices.
Required properties:
- compatible: should be
- "samsung,exynos4210-uart", for UART's compatible with Exynos4210 uart ports.
- reg: base physical address of the controller and length of memory mapped
region.
- interrupts: interrupt number to the cpu. The interrupt specifier format depends
on the interrupt controller parent.
Tegra SOC USB controllers
The device node for a USB controller that is part of a Tegra
SOC is as described in the document "Open Firmware Recommended
Practice : Universal Serial Bus" with the following modifications
and additions :
Required properties :
- compatible : Should be "nvidia,tegra20-ehci" for USB controllers
used in host mode.
- phy_type : Should be one of "ulpi" or "utmi".
- nvidia,vbus-gpio : If present, specifies a gpio that needs to be
activated for the bus to be powered.
/*
* Samsung's Exynos4210 based Origen board device tree source
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
* Copyright (c) 2010-2011 Linaro Ltd.
* www.linaro.org
*
* Device tree source file for Insignal's Origen board which is based on
* Samsung's Exynos4210 SoC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/dts-v1/;
/include/ "exynos4210.dtsi"
/ {
model = "Insignal Origen evaluation board based on Exynos4210";
compatible = "insignal,origen", "samsung,exynos4210";
memory {
reg = <0x40000000 0x40000000>;
};
chosen {
bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc";
};
sdhci@12530000 {
samsung,sdhci-bus-width = <4>;
linux,mmc_cap_4_bit_data;
samsung,sdhci-cd-internal;
gpio-cd = <&gpk2 2 2 3 3>;
gpios = <&gpk2 0 2 0 3>,
<&gpk2 1 2 0 3>,
<&gpk2 3 2 3 3>,
<&gpk2 4 2 3 3>,
<&gpk2 5 2 3 3>,
<&gpk2 6 2 3 3>;
};
sdhci@12510000 {
samsung,sdhci-bus-width = <4>;
linux,mmc_cap_4_bit_data;
samsung,sdhci-cd-internal;
gpio-cd = <&gpk0 2 2 3 3>;
gpios = <&gpk0 0 2 0 3>,
<&gpk0 1 2 0 3>,
<&gpk0 3 2 3 3>,
<&gpk0 4 2 3 3>,
<&gpk0 5 2 3 3>,
<&gpk0 6 2 3 3>;
};
gpio_keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
up {
label = "Up";
gpios = <&gpx2 0 0 0 2>;
linux,code = <103>;
};
down {
label = "Down";
gpios = <&gpx2 1 0 0 2>;
linux,code = <108>;
};
back {
label = "Back";
gpios = <&gpx1 7 0 0 2>;
linux,code = <158>;
};
home {
label = "Home";
gpios = <&gpx1 6 0 0 2>;
linux,code = <102>;
};
menu {
label = "Menu";
gpios = <&gpx1 5 0 0 2>;
linux,code = <139>;
};
};
keypad@100A0000 {
status = "disabled";
};
sdhci@12520000 {
status = "disabled";
};
sdhci@12540000 {
status = "disabled";
};
i2c@13860000 {
status = "disabled";
};
i2c@13870000 {
status = "disabled";
};
i2c@13880000 {
status = "disabled";
};
i2c@13890000 {
status = "disabled";
};
i2c@138A0000 {
status = "disabled";
};
i2c@138B0000 {
status = "disabled";
};
i2c@138C0000 {
status = "disabled";
};
i2c@138D0000 {
status = "disabled";
};
};
/*
* Samsung's Exynos4210 based SMDKV310 board device tree source
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
* Copyright (c) 2010-2011 Linaro Ltd.
* www.linaro.org
*
* Device tree source file for Samsung's SMDKV310 board which is based on
* Samsung's Exynos4210 SoC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/dts-v1/;
/include/ "exynos4210.dtsi"
/ {
model = "Samsung smdkv310 evaluation board based on Exynos4210";
compatible = "samsung,smdkv310", "samsung,exynos4210";
memory {
reg = <0x40000000 0x80000000>;
};
chosen {
bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
};
sdhci@12530000 {
samsung,sdhci-bus-width = <4>;
linux,mmc_cap_4_bit_data;
samsung,sdhci-cd-internal;
gpio-cd = <&gpk2 2 2 3 3>;
gpios = <&gpk2 0 2 0 3>,
<&gpk2 1 2 0 3>,
<&gpk2 3 2 3 3>,
<&gpk2 4 2 3 3>,
<&gpk2 5 2 3 3>,
<&gpk2 6 2 3 3>;
};
keypad@100A0000 {
samsung,keypad-num-rows = <2>;
samsung,keypad-num-columns = <8>;
linux,keypad-no-autorepeat;
linux,keypad-wakeup;
row-gpios = <&gpx2 0 3 3 0>,
<&gpx2 1 3 3 0>;
col-gpios = <&gpx1 0 3 0 0>,
<&gpx1 1 3 0 0>,
<&gpx1 2 3 0 0>,
<&gpx1 3 3 0 0>,
<&gpx1 4 3 0 0>,
<&gpx1 5 3 0 0>,
<&gpx1 6 3 0 0>,
<&gpx1 7 3 0 0>;
key_1 {
keypad,row = <0>;
keypad,column = <3>;
linux,code = <2>;
};
key_2 {
keypad,row = <0>;
keypad,column = <4>;
linux,code = <3>;
};
key_3 {
keypad,row = <0>;
keypad,column = <5>;
linux,code = <4>;
};
key_4 {
keypad,row = <0>;
keypad,column = <6>;
linux,code = <5>;
};
key_5 {
keypad,row = <0>;
keypad,column = <7>;
linux,code = <6>;
};
key_a {
keypad,row = <1>;
keypad,column = <3>;
linux,code = <30>;
};
key_b {
keypad,row = <1>;
keypad,column = <4>;
linux,code = <48>;
};
key_c {
keypad,row = <1>;
keypad,column = <5>;
linux,code = <46>;
};
key_d {
keypad,row = <1>;
keypad,column = <6>;
linux,code = <32>;
};
key_e {
keypad,row = <1>;
keypad,column = <7>;
linux,code = <18>;
};
};
i2c@13860000 {
#address-cells = <1>;
#size-cells = <0>;
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <20000>;
gpios = <&gpd1 0 2 3 0>,
<&gpd1 1 2 3 0>;
eeprom@50 {
compatible = "samsung,24ad0xd1";
reg = <0x50>;
};
eeprom@52 {
compatible = "samsung,24ad0xd1";
reg = <0x52>;
};
};
sdhci@12510000 {
status = "disabled";
};
sdhci@12520000 {
status = "disabled";
};
sdhci@12540000 {
status = "disabled";
};
i2c@13870000 {
status = "disabled";
};
i2c@13880000 {
status = "disabled";
};
i2c@13890000 {
status = "disabled";
};
i2c@138A0000 {
status = "disabled";
};
i2c@138B0000 {
status = "disabled";
};
i2c@138C0000 {
status = "disabled";
};
i2c@138D0000 {
status = "disabled";
};
};
/*
* Samsung's Exynos4210 SoC device tree source
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
* Copyright (c) 2010-2011 Linaro Ltd.
* www.linaro.org
*
* Samsung's Exynos4210 SoC device nodes are listed in this file. Exynos4210
* based board files can include this file and provide values for board specfic
* bindings.
*
* Note: This file does not include device nodes for all the controllers in
* Exynos4210 SoC. As device tree coverage for Exynos4210 increases, additional
* nodes can be added to this file.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/include/ "skeleton.dtsi"
/ {
compatible = "samsung,exynos4210";
interrupt-parent = <&gic>;
gic:interrupt-controller@10490000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
interrupt-controller;
reg = <0x10490000 0x1000>, <0x10480000 0x100>;
};
watchdog@10060000 {
compatible = "samsung,s3c2410-wdt";
reg = <0x10060000 0x100>;
interrupts = <0 43 0>;
};
rtc@10070000 {
compatible = "samsung,s3c6410-rtc";
reg = <0x10070000 0x100>;
interrupts = <0 44 0>, <0 45 0>;
};
keypad@100A0000 {
compatible = "samsung,s5pv210-keypad";
reg = <0x100A0000 0x100>;
interrupts = <0 109 0>;
};
sdhci@12510000 {
compatible = "samsung,exynos4210-sdhci";
reg = <0x12510000 0x100>;
interrupts = <0 73 0>;
};
sdhci@12520000 {
compatible = "samsung,exynos4210-sdhci";
reg = <0x12520000 0x100>;
interrupts = <0 74 0>;
};
sdhci@12530000 {
compatible = "samsung,exynos4210-sdhci";
reg = <0x12530000 0x100>;
interrupts = <0 75 0>;
};
sdhci@12540000 {
compatible = "samsung,exynos4210-sdhci";
reg = <0x12540000 0x100>;
interrupts = <0 76 0>;
};
serial@13800000 {
compatible = "samsung,exynos4210-uart";
reg = <0x13800000 0x100>;
interrupts = <0 52 0>;
};
serial@13810000 {
compatible = "samsung,exynos4210-uart";
reg = <0x13810000 0x100>;
interrupts = <0 53 0>;
};
serial@13820000 {
compatible = "samsung,exynos4210-uart";
reg = <0x13820000 0x100>;
interrupts = <0 54 0>;
};
serial@13830000 {
compatible = "samsung,exynos4210-uart";
reg = <0x13830000 0x100>;
interrupts = <0 55 0>;
};
i2c@13860000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x13860000 0x100>;
interrupts = <0 58 0>;
};
i2c@13870000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x13870000 0x100>;
interrupts = <0 59 0>;
};
i2c@13880000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x13880000 0x100>;
interrupts = <0 60 0>;
};
i2c@13890000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x13890000 0x100>;
interrupts = <0 61 0>;
};
i2c@138A0000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x138A0000 0x100>;
interrupts = <0 62 0>;
};
i2c@138B0000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x138B0000 0x100>;
interrupts = <0 63 0>;
};
i2c@138C0000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x138C0000 0x100>;
interrupts = <0 64 0>;
};
i2c@138D0000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x138D0000 0x100>;
interrupts = <0 65 0>;
};
amba {
#address-cells = <1>;
#size-cells = <1>;
compatible = "arm,amba-bus";
interrupt-parent = <&gic>;
ranges;
pdma0: pdma@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <0 35 0>;
};
pdma1: pdma@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
interrupts = <0 36 0>;
};
};
gpio-controllers {
#address-cells = <1>;
#size-cells = <1>;
gpio-controller;
ranges;
gpa0: gpio-controller@11400000 {
compatible = "samsung,exynos4-gpio";
reg = <0x11400000 0x20>;
#gpio-cells = <4>;
};
gpa1: gpio-controller@11400020 {
compatible = "samsung,exynos4-gpio";
reg = <0x11400020 0x20>;
#gpio-cells = <4>;
};
gpb: gpio-controller@11400040 {
compatible = "samsung,exynos4-gpio";
reg = <0x11400040 0x20>;
#gpio-cells = <4>;
};
gpc0: gpio-controller@11400060 {
compatible = "samsung,exynos4-gpio";
reg = <0x11400060 0x20>;
#gpio-cells = <4>;
};
gpc1: gpio-controller@11400080 {
compatible = "samsung,exynos4-gpio";
reg = <0x11400080 0x20>;
#gpio-cells = <4>;
};
gpd0: gpio-controller@114000A0 {
compatible = "samsung,exynos4-gpio";
reg = <0x114000A0 0x20>;
#gpio-cells = <4>;
};
gpd1: gpio-controller@114000C0 {
compatible = "samsung,exynos4-gpio";
reg = <0x114000C0 0x20>;
#gpio-cells = <4>;
};
gpe0: gpio-controller@114000E0 {
compatible = "samsung,exynos4-gpio";
reg = <0x114000E0 0x20>;
#gpio-cells = <4>;
};
gpe1: gpio-controller@11400100 {
compatible = "samsung,exynos4-gpio";
reg = <0x11400100 0x20>;
#gpio-cells = <4>;
};
gpe2: gpio-controller@11400120 {
compatible = "samsung,exynos4-gpio";
reg = <0x11400120 0x20>;
#gpio-cells = <4>;
};
gpe3: gpio-controller@11400140 {
compatible = "samsung,exynos4-gpio";
reg = <0x11400140 0x20>;
#gpio-cells = <4>;
};
gpe4: gpio-controller@11400160 {
compatible = "samsung,exynos4-gpio";
reg = <0x11400160 0x20>;
#gpio-cells = <4>;
};
gpf0: gpio-controller@11400180 {
compatible = "samsung,exynos4-gpio";
reg = <0x11400180 0x20>;
#gpio-cells = <4>;
};
gpf1: gpio-controller@114001A0 {
compatible = "samsung,exynos4-gpio";
reg = <0x114001A0 0x20>;
#gpio-cells = <4>;
};
gpf2: gpio-controller@114001C0 {
compatible = "samsung,exynos4-gpio";
reg = <0x114001C0 0x20>;
#gpio-cells = <4>;
};
gpf3: gpio-controller@114001E0 {
compatible = "samsung,exynos4-gpio";
reg = <0x114001E0 0x20>;
#gpio-cells = <4>;
};
gpj0: gpio-controller@11000000 {
compatible = "samsung,exynos4-gpio";
reg = <0x11000000 0x20>;
#gpio-cells = <4>;
};
gpj1: gpio-controller@11000020 {
compatible = "samsung,exynos4-gpio";
reg = <0x11000020 0x20>;
#gpio-cells = <4>;
};
gpk0: gpio-controller@11000040 {
compatible = "samsung,exynos4-gpio";
reg = <0x11000040 0x20>;
#gpio-cells = <4>;
};
gpk1: gpio-controller@11000060 {
compatible = "samsung,exynos4-gpio";
reg = <0x11000060 0x20>;
#gpio-cells = <4>;
};
gpk2: gpio-controller@11000080 {
compatible = "samsung,exynos4-gpio";
reg = <0x11000080 0x20>;
#gpio-cells = <4>;
};
gpk3: gpio-controller@110000A0 {
compatible = "samsung,exynos4-gpio";
reg = <0x110000A0 0x20>;
#gpio-cells = <4>;
};
gpl0: gpio-controller@110000C0 {
compatible = "samsung,exynos4-gpio";
reg = <0x110000C0 0x20>;
#gpio-cells = <4>;
};
gpl1: gpio-controller@110000E0 {
compatible = "samsung,exynos4-gpio";
reg = <0x110000E0 0x20>;
#gpio-cells = <4>;
};
gpl2: gpio-controller@11000100 {
compatible = "samsung,exynos4-gpio";
reg = <0x11000100 0x20>;
#gpio-cells = <4>;
};
gpy0: gpio-controller@11000120 {
compatible = "samsung,exynos4-gpio";
reg = <0x11000120 0x20>;
#gpio-cells = <4>;
};
gpy1: gpio-controller@11000140 {
compatible = "samsung,exynos4-gpio";
reg = <0x11000140 0x20>;
#gpio-cells = <4>;
};
gpy2: gpio-controller@11000160 {
compatible = "samsung,exynos4-gpio";
reg = <0x11000160 0x20>;
#gpio-cells = <4>;
};
gpy3: gpio-controller@11000180 {
compatible = "samsung,exynos4-gpio";
reg = <0x11000180 0x20>;
#gpio-cells = <4>;
};
gpy4: gpio-controller@110001A0 {
compatible = "samsung,exynos4-gpio";
reg = <0x110001A0 0x20>;
#gpio-cells = <4>;
};
gpy5: gpio-controller@110001C0 {
compatible = "samsung,exynos4-gpio";
reg = <0x110001C0 0x20>;
#gpio-cells = <4>;
};
gpy6: gpio-controller@110001E0 {
compatible = "samsung,exynos4-gpio";
reg = <0x110001E0 0x20>;
#gpio-cells = <4>;
};
gpx0: gpio-controller@11000C00 {
compatible = "samsung,exynos4-gpio";
reg = <0x11000C00 0x20>;
#gpio-cells = <4>;
};
gpx1: gpio-controller@11000C20 {
compatible = "samsung,exynos4-gpio";
reg = <0x11000C20 0x20>;
#gpio-cells = <4>;
};
gpx2: gpio-controller@11000C40 {
compatible = "samsung,exynos4-gpio";
reg = <0x11000C40 0x20>;
#gpio-cells = <4>;
};
gpx3: gpio-controller@11000C60 {
compatible = "samsung,exynos4-gpio";
reg = <0x11000C60 0x20>;
#gpio-cells = <4>;
};
gpz: gpio-controller@03860000 {
compatible = "samsung,exynos4-gpio";
reg = <0x03860000 0x20>;
#gpio-cells = <4>;
};
};
};
/dts-v1/; /dts-v1/;
/memreserve/ 0x1c000000 0x04000000;
/include/ "tegra20.dtsi" /include/ "tegra20.dtsi"
/ { / {
model = "NVIDIA Tegra2 Harmony evaluation board"; model = "NVIDIA Tegra2 Harmony evaluation board";
compatible = "nvidia,harmony", "nvidia,tegra20"; compatible = "nvidia,harmony", "nvidia,tegra20";
chosen {
bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk0p2 rw rootwait";
};
memory@0 { memory@0 {
reg = < 0x00000000 0x40000000 >; reg = < 0x00000000 0x40000000 >;
}; };
...@@ -52,16 +47,40 @@ sound { ...@@ -52,16 +47,40 @@ sound {
ext-mic-en-gpios = <&gpio 185 0>; ext-mic-en-gpios = <&gpio 185 0>;
}; };
serial@70006000 {
status = "disable";
};
serial@70006040 {
status = "disable";
};
serial@70006200 {
status = "disable";
};
serial@70006300 { serial@70006300 {
clock-frequency = < 216000000 >; clock-frequency = < 216000000 >;
}; };
serial@70006400 {
status = "disable";
};
sdhci@c8000000 {
status = "disable";
};
sdhci@c8000200 { sdhci@c8000200 {
cd-gpios = <&gpio 69 0>; /* gpio PI5 */ cd-gpios = <&gpio 69 0>; /* gpio PI5 */
wp-gpios = <&gpio 57 0>; /* gpio PH1 */ wp-gpios = <&gpio 57 0>; /* gpio PH1 */
power-gpios = <&gpio 155 0>; /* gpio PT3 */ power-gpios = <&gpio 155 0>; /* gpio PT3 */
}; };
sdhci@c8000400 {
status = "disable";
};
sdhci@c8000600 { sdhci@c8000600 {
cd-gpios = <&gpio 58 0>; /* gpio PH2 */ cd-gpios = <&gpio 58 0>; /* gpio PH2 */
wp-gpios = <&gpio 59 0>; /* gpio PH3 */ wp-gpios = <&gpio 59 0>; /* gpio PH3 */
......
/dts-v1/;
/include/ "tegra20.dtsi"
/ {
model = "Toshiba AC100 / Dynabook AZ";
compatible = "compal,paz00", "nvidia,tegra20";
memory@0 {
reg = <0x00000000 0x20000000>;
};
i2c@7000c000 {
clock-frequency = <400000>;
};
i2c@7000c400 {
clock-frequency = <400000>;
};
i2c@7000c500 {
status = "disable";
};
nvec@7000c500 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "nvidia,nvec";
reg = <0x7000C500 0x100>;
interrupts = <0 92 0x04>;
clock-frequency = <80000>;
request-gpios = <&gpio 170 0>;
slave-addr = <138>;
};
i2c@7000d000 {
clock-frequency = <400000>;
};
serial@70006000 {
clock-frequency = <216000000>;
};
serial@70006040 {
status = "disable";
};
serial@70006200 {
status = "disable";
};
serial@70006300 {
clock-frequency = <216000000>;
};
serial@70006400 {
status = "disable";
};
sdhci@c8000000 {
cd-gpios = <&gpio 173 0>; /* gpio PV5 */
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
power-gpios = <&gpio 155 0>; /* gpio PT3 */
};
sdhci@c8000200 {
status = "disable";
};
sdhci@c8000400 {
status = "disable";
};
sdhci@c8000600 {
support-8bit;
};
};
/dts-v1/; /dts-v1/;
/memreserve/ 0x1c000000 0x04000000;
/include/ "tegra20.dtsi" /include/ "tegra20.dtsi"
/ { / {
model = "NVIDIA Seaboard"; model = "NVIDIA Seaboard";
compatible = "nvidia,seaboard", "nvidia,tegra20"; compatible = "nvidia,seaboard", "nvidia,tegra20";
chosen {
bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk1p3 rw rootwait";
};
memory { memory {
device_type = "memory"; device_type = "memory";
reg = < 0x00000000 0x40000000 >; reg = < 0x00000000 0x40000000 >;
}; };
i2c@7000c000 {
clock-frequency = <400000>;
};
i2c@7000c400 {
clock-frequency = <400000>;
};
i2c@7000c500 {
clock-frequency = <400000>;
};
i2c@7000d000 {
clock-frequency = <400000>;
adt7461@4c {
compatible = "adt7461";
reg = <0x4c>;
};
};
serial@70006000 {
status = "disable";
};
serial@70006040 {
status = "disable";
};
serial@70006200 {
status = "disable";
};
serial@70006300 { serial@70006300 {
clock-frequency = < 216000000 >; clock-frequency = < 216000000 >;
}; };
serial@70006400 {
status = "disable";
};
sdhci@c8000000 {
status = "disable";
};
sdhci@c8000200 {
status = "disable";
};
sdhci@c8000400 { sdhci@c8000400 {
cd-gpios = <&gpio 69 0>; /* gpio PI5 */ cd-gpios = <&gpio 69 0>; /* gpio PI5 */
wp-gpios = <&gpio 57 0>; /* gpio PH1 */ wp-gpios = <&gpio 57 0>; /* gpio PH1 */
...@@ -29,4 +69,28 @@ sdhci@c8000400 { ...@@ -29,4 +69,28 @@ sdhci@c8000400 {
sdhci@c8000600 { sdhci@c8000600 {
support-8bit; support-8bit;
}; };
usb@c5000000 {
nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */
};
gpio-keys {
compatible = "gpio-keys";
power {
label = "Power";
gpios = <&gpio 170 1>; /* gpio PV2, active low */
linux,code = <116>; /* KEY_POWER */
gpio-key,wakeup;
};
lid {
label = "Lid";
gpios = <&gpio 23 0>; /* gpio PC7 */
linux,input-type = <5>; /* EV_SW */
linux,code = <0>; /* SW_LID */
debounce-interval = <1>;
gpio-key,wakeup;
};
};
}; };
/dts-v1/;
/include/ "tegra20.dtsi"
/ {
model = "Compulab TrimSlice board";
compatible = "compulab,trimslice", "nvidia,tegra20";
memory@0 {
reg = < 0x00000000 0x40000000 >;
};
i2c@7000c000 {
clock-frequency = <400000>;
};
i2c@7000c400 {
clock-frequency = <400000>;
};
i2c@7000c500 {
clock-frequency = <400000>;
};
i2c@7000d000 {
status = "disable";
};
serial@70006000 {
clock-frequency = < 216000000 >;
};
serial@70006040 {
status = "disable";
};
serial@70006200 {
status = "disable";
};
serial@70006300 {
status = "disable";
};
serial@70006400 {
status = "disable";
};
sdhci@c8000000 {
status = "disable";
};
sdhci@c8000200 {
status = "disable";
};
sdhci@c8000400 {
status = "disable";
};
sdhci@c8000600 {
cd-gpios = <&gpio 121 0>;
wp-gpios = <&gpio 122 0>;
};
};
/dts-v1/; /dts-v1/;
/memreserve/ 0x1c000000 0x04000000;
/include/ "tegra20.dtsi" /include/ "tegra20.dtsi"
/ { / {
model = "NVIDIA Tegra2 Ventana evaluation board"; model = "NVIDIA Tegra2 Ventana evaluation board";
compatible = "nvidia,ventana", "nvidia,tegra20"; compatible = "nvidia,ventana", "nvidia,tegra20";
chosen {
bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/ram rdinit=/sbin/init";
};
memory { memory {
reg = < 0x00000000 0x40000000 >; reg = < 0x00000000 0x40000000 >;
}; };
i2c@7000c000 {
clock-frequency = <400000>;
};
i2c@7000c400 {
clock-frequency = <400000>;
};
i2c@7000c500 {
clock-frequency = <400000>;
};
i2c@7000d000 {
clock-frequency = <400000>;
};
serial@70006000 {
status = "disable";
};
serial@70006040 {
status = "disable";
};
serial@70006200 {
status = "disable";
};
serial@70006300 { serial@70006300 {
clock-frequency = < 216000000 >; clock-frequency = < 216000000 >;
}; };
serial@70006400 {
status = "disable";
};
sdhci@c8000000 {
status = "disable";
};
sdhci@c8000200 {
status = "disable";
};
sdhci@c8000400 { sdhci@c8000400 {
cd-gpios = <&gpio 69 0>; /* gpio PI5 */ cd-gpios = <&gpio 69 0>; /* gpio PI5 */
wp-gpios = <&gpio 57 0>; /* gpio PH1 */ wp-gpios = <&gpio 57 0>; /* gpio PH1 */
......
...@@ -5,9 +5,9 @@ / { ...@@ -5,9 +5,9 @@ / {
interrupt-parent = <&intc>; interrupt-parent = <&intc>;
intc: interrupt-controller@50041000 { intc: interrupt-controller@50041000 {
compatible = "nvidia,tegra20-gic"; compatible = "arm,cortex-a9-gic";
interrupt-controller; interrupt-controller;
#interrupt-cells = <1>; #interrupt-cells = <3>;
reg = < 0x50041000 0x1000 >, reg = < 0x50041000 0x1000 >,
< 0x50040100 0x0100 >; < 0x50040100 0x0100 >;
}; };
...@@ -17,7 +17,7 @@ i2c@7000c000 { ...@@ -17,7 +17,7 @@ i2c@7000c000 {
#size-cells = <0>; #size-cells = <0>;
compatible = "nvidia,tegra20-i2c"; compatible = "nvidia,tegra20-i2c";
reg = <0x7000C000 0x100>; reg = <0x7000C000 0x100>;
interrupts = < 70 >; interrupts = < 0 38 0x04 >;
}; };
i2c@7000c400 { i2c@7000c400 {
...@@ -25,7 +25,7 @@ i2c@7000c400 { ...@@ -25,7 +25,7 @@ i2c@7000c400 {
#size-cells = <0>; #size-cells = <0>;
compatible = "nvidia,tegra20-i2c"; compatible = "nvidia,tegra20-i2c";
reg = <0x7000C400 0x100>; reg = <0x7000C400 0x100>;
interrupts = < 116 >; interrupts = < 0 84 0x04 >;
}; };
i2c@7000c500 { i2c@7000c500 {
...@@ -33,38 +33,32 @@ i2c@7000c500 { ...@@ -33,38 +33,32 @@ i2c@7000c500 {
#size-cells = <0>; #size-cells = <0>;
compatible = "nvidia,tegra20-i2c"; compatible = "nvidia,tegra20-i2c";
reg = <0x7000C500 0x100>; reg = <0x7000C500 0x100>;
interrupts = < 124 >; interrupts = < 0 92 0x04 >;
}; };
i2c@7000d000 { i2c@7000d000 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
compatible = "nvidia,tegra20-i2c"; compatible = "nvidia,tegra20-i2c-dvc";
reg = <0x7000D000 0x200>; reg = <0x7000D000 0x200>;
interrupts = < 85 >; interrupts = < 0 53 0x04 >;
}; };
i2s@70002800 { i2s@70002800 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "nvidia,tegra20-i2s"; compatible = "nvidia,tegra20-i2s";
reg = <0x70002800 0x200>; reg = <0x70002800 0x200>;
interrupts = < 45 >; interrupts = < 0 13 0x04 >;
dma-channel = < 2 >; dma-channel = < 2 >;
}; };
i2s@70002a00 { i2s@70002a00 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "nvidia,tegra20-i2s"; compatible = "nvidia,tegra20-i2s";
reg = <0x70002a00 0x200>; reg = <0x70002a00 0x200>;
interrupts = < 35 >; interrupts = < 0 3 0x04 >;
dma-channel = < 1 >; dma-channel = < 1 >;
}; };
das@70000c00 { das@70000c00 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "nvidia,tegra20-das"; compatible = "nvidia,tegra20-das";
reg = <0x70000c00 0x80>; reg = <0x70000c00 0x80>;
}; };
...@@ -72,7 +66,13 @@ das@70000c00 { ...@@ -72,7 +66,13 @@ das@70000c00 {
gpio: gpio@6000d000 { gpio: gpio@6000d000 {
compatible = "nvidia,tegra20-gpio"; compatible = "nvidia,tegra20-gpio";
reg = < 0x6000d000 0x1000 >; reg = < 0x6000d000 0x1000 >;
interrupts = < 64 65 66 67 87 119 121 >; interrupts = < 0 32 0x04
0 33 0x04
0 34 0x04
0 35 0x04
0 55 0x04
0 87 0x04
0 89 0x04 >;
#gpio-cells = <2>; #gpio-cells = <2>;
gpio-controller; gpio-controller;
}; };
...@@ -89,59 +89,80 @@ serial@70006000 { ...@@ -89,59 +89,80 @@ serial@70006000 {
compatible = "nvidia,tegra20-uart"; compatible = "nvidia,tegra20-uart";
reg = <0x70006000 0x40>; reg = <0x70006000 0x40>;
reg-shift = <2>; reg-shift = <2>;
interrupts = < 68 >; interrupts = < 0 36 0x04 >;
}; };
serial@70006040 { serial@70006040 {
compatible = "nvidia,tegra20-uart"; compatible = "nvidia,tegra20-uart";
reg = <0x70006040 0x40>; reg = <0x70006040 0x40>;
reg-shift = <2>; reg-shift = <2>;
interrupts = < 69 >; interrupts = < 0 37 0x04 >;
}; };
serial@70006200 { serial@70006200 {
compatible = "nvidia,tegra20-uart"; compatible = "nvidia,tegra20-uart";
reg = <0x70006200 0x100>; reg = <0x70006200 0x100>;
reg-shift = <2>; reg-shift = <2>;
interrupts = < 78 >; interrupts = < 0 46 0x04 >;
}; };
serial@70006300 { serial@70006300 {
compatible = "nvidia,tegra20-uart"; compatible = "nvidia,tegra20-uart";
reg = <0x70006300 0x100>; reg = <0x70006300 0x100>;
reg-shift = <2>; reg-shift = <2>;
interrupts = < 122 >; interrupts = < 0 90 0x04 >;
}; };
serial@70006400 { serial@70006400 {
compatible = "nvidia,tegra20-uart"; compatible = "nvidia,tegra20-uart";
reg = <0x70006400 0x100>; reg = <0x70006400 0x100>;
reg-shift = <2>; reg-shift = <2>;
interrupts = < 123 >; interrupts = < 0 91 0x04 >;
}; };
sdhci@c8000000 { sdhci@c8000000 {
compatible = "nvidia,tegra20-sdhci"; compatible = "nvidia,tegra20-sdhci";
reg = <0xc8000000 0x200>; reg = <0xc8000000 0x200>;
interrupts = < 46 >; interrupts = < 0 14 0x04 >;
}; };
sdhci@c8000200 { sdhci@c8000200 {
compatible = "nvidia,tegra20-sdhci"; compatible = "nvidia,tegra20-sdhci";
reg = <0xc8000200 0x200>; reg = <0xc8000200 0x200>;
interrupts = < 47 >; interrupts = < 0 15 0x04 >;
}; };
sdhci@c8000400 { sdhci@c8000400 {
compatible = "nvidia,tegra20-sdhci"; compatible = "nvidia,tegra20-sdhci";
reg = <0xc8000400 0x200>; reg = <0xc8000400 0x200>;
interrupts = < 51 >; interrupts = < 0 19 0x04 >;
}; };
sdhci@c8000600 { sdhci@c8000600 {
compatible = "nvidia,tegra20-sdhci"; compatible = "nvidia,tegra20-sdhci";
reg = <0xc8000600 0x200>; reg = <0xc8000600 0x200>;
interrupts = < 63 >; interrupts = < 0 31 0x04 >;
};
usb@c5000000 {
compatible = "nvidia,tegra20-ehci", "usb-ehci";
reg = <0xc5000000 0x4000>;
interrupts = < 0 20 0x04 >;
phy_type = "utmi";
};
usb@c5004000 {
compatible = "nvidia,tegra20-ehci", "usb-ehci";
reg = <0xc5004000 0x4000>;
interrupts = < 0 21 0x04 >;
phy_type = "ulpi";
};
usb@c5008000 {
compatible = "nvidia,tegra20-ehci", "usb-ehci";
reg = <0xc5008000 0x4000>;
interrupts = < 0 97 0x04 >;
phy_type = "utmi";
}; };
}; };
/include/ "skeleton.dtsi"
/ {
compatible = "nvidia,tegra30";
interrupt-parent = <&intc>;
intc: interrupt-controller@50041000 {
compatible = "arm,cortex-a9-gic";
interrupt-controller;
#interrupt-cells = <3>;
reg = < 0x50041000 0x1000 >,
< 0x50040100 0x0100 >;
};
i2c@7000c000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
reg = <0x7000C000 0x100>;
interrupts = < 0 38 0x04 >;
};
i2c@7000c400 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
reg = <0x7000C400 0x100>;
interrupts = < 0 84 0x04 >;
};
i2c@7000c500 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
reg = <0x7000C500 0x100>;
interrupts = < 0 92 0x04 >;
};
i2c@7000c700 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
reg = <0x7000c700 0x100>;
interrupts = < 0 120 0x04 >;
};
i2c@7000d000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
reg = <0x7000D000 0x100>;
interrupts = < 0 53 0x04 >;
};
gpio: gpio@6000d000 {
compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio";
reg = < 0x6000d000 0x1000 >;
interrupts = < 0 32 0x04 0 33 0x04 0 34 0x04 0 35 0x04 0 55 0x04 0 87 0x04 0 89 0x04 >;
#gpio-cells = <2>;
gpio-controller;
};
serial@70006000 {
compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
reg = <0x70006000 0x40>;
reg-shift = <2>;
interrupts = < 0 36 0x04 >;
};
serial@70006040 {
compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
reg = <0x70006040 0x40>;
reg-shift = <2>;
interrupts = < 0 37 0x04 >;
};
serial@70006200 {
compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
reg = <0x70006200 0x100>;
reg-shift = <2>;
interrupts = < 0 46 0x04 >;
};
serial@70006300 {
compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
reg = <0x70006300 0x100>;
reg-shift = <2>;
interrupts = < 0 90 0x04 >;
};
serial@70006400 {
compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
reg = <0x70006400 0x100>;
reg-shift = <2>;
interrupts = < 0 91 0x04 >;
};
sdhci@78000000 {
compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
reg = <0x78000000 0x200>;
interrupts = < 0 14 0x04 >;
};
sdhci@78000200 {
compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
reg = <0x78000200 0x200>;
interrupts = < 0 15 0x04 >;
};
sdhci@78000400 {
compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
reg = <0x78000400 0x200>;
interrupts = < 0 19 0x04 >;
};
sdhci@78000600 {
compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
reg = <0x78000600 0x200>;
interrupts = < 0 31 0x04 >;
};
pinmux: pinmux@70000000 {
compatible = "nvidia,tegra30-pinmux";
reg = < 0x70000868 0xd0 /* Pad control registers */
0x70003000 0x3e0 >; /* Mux registers */
};
};
...@@ -59,6 +59,11 @@ config EXYNOS4_MCT ...@@ -59,6 +59,11 @@ config EXYNOS4_MCT
help help
Use MCT (Multi Core Timer) as kernel timers Use MCT (Multi Core Timer) as kernel timers
config EXYNOS4_DEV_DMA
bool
help
Compile in amba device definitions for DMA controller
config EXYNOS4_DEV_AHCI config EXYNOS4_DEV_AHCI
bool bool
help help
...@@ -179,6 +184,7 @@ config MACH_SMDKV310 ...@@ -179,6 +184,7 @@ config MACH_SMDKV310
select SAMSUNG_DEV_BACKLIGHT select SAMSUNG_DEV_BACKLIGHT
select EXYNOS4_DEV_AHCI select EXYNOS4_DEV_AHCI
select SAMSUNG_DEV_KEYPAD select SAMSUNG_DEV_KEYPAD
select EXYNOS4_DEV_DMA
select EXYNOS4_DEV_PD select EXYNOS4_DEV_PD
select SAMSUNG_DEV_PWM select SAMSUNG_DEV_PWM
select EXYNOS4_DEV_SYSMMU select EXYNOS4_DEV_SYSMMU
...@@ -199,6 +205,7 @@ config MACH_ARMLEX4210 ...@@ -199,6 +205,7 @@ config MACH_ARMLEX4210
select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3 select S3C_DEV_HSMMC3
select EXYNOS4_DEV_AHCI select EXYNOS4_DEV_AHCI
select EXYNOS4_DEV_DMA
select EXYNOS4_DEV_SYSMMU select EXYNOS4_DEV_SYSMMU
select EXYNOS4_SETUP_SDHCI select EXYNOS4_SETUP_SDHCI
help help
...@@ -224,6 +231,7 @@ config MACH_UNIVERSAL_C210 ...@@ -224,6 +231,7 @@ config MACH_UNIVERSAL_C210
select S5P_DEV_MFC select S5P_DEV_MFC
select S5P_DEV_ONENAND select S5P_DEV_ONENAND
select S5P_DEV_TV select S5P_DEV_TV
select EXYNOS4_DEV_DMA
select EXYNOS4_DEV_PD select EXYNOS4_DEV_PD
select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_FIMD0
select EXYNOS4_SETUP_I2C1 select EXYNOS4_SETUP_I2C1
...@@ -257,6 +265,7 @@ config MACH_NURI ...@@ -257,6 +265,7 @@ config MACH_NURI
select S5P_DEV_MFC select S5P_DEV_MFC
select S5P_DEV_USB_EHCI select S5P_DEV_USB_EHCI
select S5P_SETUP_MIPIPHY select S5P_SETUP_MIPIPHY
select EXYNOS4_DEV_DMA
select EXYNOS4_DEV_PD select EXYNOS4_DEV_PD
select EXYNOS4_SETUP_FIMC select EXYNOS4_SETUP_FIMC
select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_FIMD0
...@@ -289,6 +298,7 @@ config MACH_ORIGEN ...@@ -289,6 +298,7 @@ config MACH_ORIGEN
select S5P_DEV_USB_EHCI select S5P_DEV_USB_EHCI
select SAMSUNG_DEV_BACKLIGHT select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM select SAMSUNG_DEV_PWM
select EXYNOS4_DEV_DMA
select EXYNOS4_DEV_PD select EXYNOS4_DEV_PD
select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_FIMD0
select EXYNOS4_SETUP_SDHCI select EXYNOS4_SETUP_SDHCI
...@@ -329,6 +339,20 @@ config MACH_SMDK4412 ...@@ -329,6 +339,20 @@ config MACH_SMDK4412
Machine support for Samsung SMDK4412 Machine support for Samsung SMDK4412
endif endif
comment "Flattened Device Tree based board for Exynos4 based SoC"
config MACH_EXYNOS4_DT
bool "Samsung Exynos4 Machine using device tree"
select CPU_EXYNOS4210
select USE_OF
select ARM_AMBA
select HAVE_SAMSUNG_KEYPAD if INPUT_KEYBOARD
help
Machine support for Samsung Exynos4 machine with device tree enabled.
Select this if a fdt blob is available for the Exynos4 SoC based board.
Note: This is under development and not all peripherals can be supported
with this machine file.
if ARCH_EXYNOS4 if ARCH_EXYNOS4
comment "Configuration for HSMMC 8-bit bus width" comment "Configuration for HSMMC 8-bit bus width"
......
...@@ -19,7 +19,7 @@ obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o ...@@ -19,7 +19,7 @@ obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o
obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_ARCH_EXYNOS4) += dma.o pmu.o obj-$(CONFIG_ARCH_EXYNOS4) += pmu.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o
...@@ -39,6 +39,8 @@ obj-$(CONFIG_MACH_ORIGEN) += mach-origen.o ...@@ -39,6 +39,8 @@ obj-$(CONFIG_MACH_ORIGEN) += mach-origen.o
obj-$(CONFIG_MACH_SMDK4212) += mach-smdk4x12.o obj-$(CONFIG_MACH_SMDK4212) += mach-smdk4x12.o
obj-$(CONFIG_MACH_SMDK4412) += mach-smdk4x12.o obj-$(CONFIG_MACH_SMDK4412) += mach-smdk4x12.o
obj-$(CONFIG_MACH_EXYNOS4_DT) += mach-exynos4-dt.o
# device support # device support
obj-$(CONFIG_ARCH_EXYNOS4) += dev-audio.o obj-$(CONFIG_ARCH_EXYNOS4) += dev-audio.o
...@@ -46,6 +48,7 @@ obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o ...@@ -46,6 +48,7 @@ obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o
obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o
obj-$(CONFIG_EXYNOS4_DEV_DMA) += dma.o
obj-$(CONFIG_ARCH_EXYNOS4) += setup-i2c0.o obj-$(CONFIG_ARCH_EXYNOS4) += setup-i2c0.o
obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
......
...@@ -553,16 +553,6 @@ static struct clk init_clocks_off[] = { ...@@ -553,16 +553,6 @@ static struct clk init_clocks_off[] = {
.devname = "s5p-sdo", .devname = "s5p-sdo",
.enable = exynos4_clk_dac_ctrl, .enable = exynos4_clk_dac_ctrl,
.ctrlbit = (1 << 0), .ctrlbit = (1 << 0),
}, {
.name = "dma",
.devname = "dma-pl330.0",
.enable = exynos4_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 0),
}, {
.name = "dma",
.devname = "dma-pl330.1",
.enable = exynos4_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 1),
}, { }, {
.name = "adc", .name = "adc",
.enable = exynos4_clk_ip_peril_ctrl, .enable = exynos4_clk_ip_peril_ctrl,
...@@ -779,6 +769,20 @@ static struct clk init_clocks[] = { ...@@ -779,6 +769,20 @@ static struct clk init_clocks[] = {
} }
}; };
static struct clk clk_pdma0 = {
.name = "dma",
.devname = "dma-pl330.0",
.enable = exynos4_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 0),
};
static struct clk clk_pdma1 = {
.name = "dma",
.devname = "dma-pl330.1",
.enable = exynos4_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 1),
};
struct clk *clkset_group_list[] = { struct clk *clkset_group_list[] = {
[0] = &clk_ext_xtal_mux, [0] = &clk_ext_xtal_mux,
[1] = &clk_xusbxti, [1] = &clk_xusbxti,
...@@ -1010,46 +1014,6 @@ static struct clksrc_clk clk_dout_mmc4 = { ...@@ -1010,46 +1014,6 @@ static struct clksrc_clk clk_dout_mmc4 = {
static struct clksrc_clk clksrcs[] = { static struct clksrc_clk clksrcs[] = {
{ {
.clk = {
.name = "uclk1",
.devname = "s5pv210-uart.0",
.enable = exynos4_clksrc_mask_peril0_ctrl,
.ctrlbit = (1 << 0),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "uclk1",
.devname = "s5pv210-uart.1",
.enable = exynos4_clksrc_mask_peril0_ctrl,
.ctrlbit = (1 << 4),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
}, {
.clk = {
.name = "uclk1",
.devname = "s5pv210-uart.2",
.enable = exynos4_clksrc_mask_peril0_ctrl,
.ctrlbit = (1 << 8),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
}, {
.clk = {
.name = "uclk1",
.devname = "s5pv210-uart.3",
.enable = exynos4_clksrc_mask_peril0_ctrl,
.ctrlbit = (1 << 12),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
}, {
.clk = { .clk = {
.name = "sclk_pwm", .name = "sclk_pwm",
.enable = exynos4_clksrc_mask_peril0_ctrl, .enable = exynos4_clksrc_mask_peril0_ctrl,
...@@ -1238,6 +1202,54 @@ static struct clksrc_clk clksrcs[] = { ...@@ -1238,6 +1202,54 @@ static struct clksrc_clk clksrcs[] = {
} }
}; };
static struct clksrc_clk clk_sclk_uart0 = {
.clk = {
.name = "uclk1",
.devname = "exynos4210-uart.0",
.enable = exynos4_clksrc_mask_peril0_ctrl,
.ctrlbit = (1 << 0),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
};
static struct clksrc_clk clk_sclk_uart1 = {
.clk = {
.name = "uclk1",
.devname = "exynos4210-uart.1",
.enable = exynos4_clksrc_mask_peril0_ctrl,
.ctrlbit = (1 << 4),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
};
static struct clksrc_clk clk_sclk_uart2 = {
.clk = {
.name = "uclk1",
.devname = "exynos4210-uart.2",
.enable = exynos4_clksrc_mask_peril0_ctrl,
.ctrlbit = (1 << 8),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
};
static struct clksrc_clk clk_sclk_uart3 = {
.clk = {
.name = "uclk1",
.devname = "exynos4210-uart.3",
.enable = exynos4_clksrc_mask_peril0_ctrl,
.ctrlbit = (1 << 12),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
};
/* Clock initialization code */ /* Clock initialization code */
static struct clksrc_clk *sysclks[] = { static struct clksrc_clk *sysclks[] = {
&clk_mout_apll, &clk_mout_apll,
...@@ -1272,6 +1284,27 @@ static struct clksrc_clk *sysclks[] = { ...@@ -1272,6 +1284,27 @@ static struct clksrc_clk *sysclks[] = {
&clk_mout_mfc1, &clk_mout_mfc1,
}; };
static struct clk *clk_cdev[] = {
&clk_pdma0,
&clk_pdma1,
};
static struct clksrc_clk *clksrc_cdev[] = {
&clk_sclk_uart0,
&clk_sclk_uart1,
&clk_sclk_uart2,
&clk_sclk_uart3,
};
static struct clk_lookup exynos4_clk_lookup[] = {
CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &clk_sclk_uart0.clk),
CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &clk_sclk_uart1.clk),
CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &clk_sclk_uart2.clk),
CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &clk_sclk_uart3.clk),
CLKDEV_INIT("dma-pl330.0", "apb_pclk", &clk_pdma0),
CLKDEV_INIT("dma-pl330.1", "apb_pclk", &clk_pdma1),
};
static int xtal_rate; static int xtal_rate;
static unsigned long exynos4_fout_apll_get_rate(struct clk *clk) static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
...@@ -1479,11 +1512,19 @@ void __init exynos4_register_clocks(void) ...@@ -1479,11 +1512,19 @@ void __init exynos4_register_clocks(void)
for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++) for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
s3c_register_clksrc(sclk_tv[ptr], 1); s3c_register_clksrc(sclk_tv[ptr], 1);
for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
s3c_register_clksrc(clksrc_cdev[ptr], 1);
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++)
s3c_disable_clocks(clk_cdev[ptr], 1);
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup));
register_syscore_ops(&exynos4_clock_syscore_ops); register_syscore_ops(&exynos4_clock_syscore_ops);
s3c24xx_register_clock(&dummy_apb_pclk); s3c24xx_register_clock(&dummy_apb_pclk);
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <asm/proc-fns.h> #include <asm/proc-fns.h>
#include <asm/exception.h> #include <asm/exception.h>
...@@ -385,6 +387,13 @@ static void __init combiner_init(unsigned int combiner_nr, void __iomem *base, ...@@ -385,6 +387,13 @@ static void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
} }
} }
#ifdef CONFIG_OF
static const struct of_device_id exynos4_dt_irq_match[] = {
{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
{},
};
#endif
void __init exynos4_init_irq(void) void __init exynos4_init_irq(void)
{ {
int irq; int irq;
...@@ -392,7 +401,12 @@ void __init exynos4_init_irq(void) ...@@ -392,7 +401,12 @@ void __init exynos4_init_irq(void)
gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset); if (!of_have_populated_dt())
gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset);
#ifdef CONFIG_OF
else
of_irq_init(exynos4_dt_irq_match);
#endif
for (irq = 0; irq < MAX_COMBINER_NR; irq++) { for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
...@@ -460,15 +474,6 @@ int __init exynos_init(void) ...@@ -460,15 +474,6 @@ int __init exynos_init(void)
return device_register(&exynos4_dev); return device_register(&exynos4_dev);
} }
static struct s3c24xx_uart_clksrc exynos4_serial_clocks[] = {
[0] = {
.name = "uclk1",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
},
};
/* uart registration process */ /* uart registration process */
void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no) void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no)
...@@ -476,16 +481,10 @@ void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no) ...@@ -476,16 +481,10 @@ void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no)
struct s3c2410_uartcfg *tcfg = cfg; struct s3c2410_uartcfg *tcfg = cfg;
u32 ucnt; u32 ucnt;
for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { for (ucnt = 0; ucnt < no; ucnt++, tcfg++)
if (!tcfg->clocks) { tcfg->has_fracval = 1;
tcfg->has_fracval = 1;
tcfg->clocks = exynos4_serial_clocks;
tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks);
}
tcfg->flags |= NO_NEED_CHECK_CLKSRC;
}
s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no); s3c24xx_init_uartdevs("exynos4210-uart", s5p_uart_resources, cfg, no);
} }
static DEFINE_SPINLOCK(eint_lock); static DEFINE_SPINLOCK(eint_lock);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/amba/bus.h> #include <linux/amba/bus.h>
#include <linux/amba/pl330.h> #include <linux/amba/pl330.h>
#include <linux/of.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <plat/devs.h> #include <plat/devs.h>
...@@ -35,95 +36,42 @@ ...@@ -35,95 +36,42 @@
static u64 dma_dmamask = DMA_BIT_MASK(32); static u64 dma_dmamask = DMA_BIT_MASK(32);
struct dma_pl330_peri pdma0_peri[28] = { u8 pdma0_peri[] = {
{ DMACH_PCM0_RX,
.peri_id = (u8)DMACH_PCM0_RX, DMACH_PCM0_TX,
.rqtype = DEVTOMEM, DMACH_PCM2_RX,
}, { DMACH_PCM2_TX,
.peri_id = (u8)DMACH_PCM0_TX, DMACH_MSM_REQ0,
.rqtype = MEMTODEV, DMACH_MSM_REQ2,
}, { DMACH_SPI0_RX,
.peri_id = (u8)DMACH_PCM2_RX, DMACH_SPI0_TX,
.rqtype = DEVTOMEM, DMACH_SPI2_RX,
}, { DMACH_SPI2_TX,
.peri_id = (u8)DMACH_PCM2_TX, DMACH_I2S0S_TX,
.rqtype = MEMTODEV, DMACH_I2S0_RX,
}, { DMACH_I2S0_TX,
.peri_id = (u8)DMACH_MSM_REQ0, DMACH_I2S2_RX,
}, { DMACH_I2S2_TX,
.peri_id = (u8)DMACH_MSM_REQ2, DMACH_UART0_RX,
}, { DMACH_UART0_TX,
.peri_id = (u8)DMACH_SPI0_RX, DMACH_UART2_RX,
.rqtype = DEVTOMEM, DMACH_UART2_TX,
}, { DMACH_UART4_RX,
.peri_id = (u8)DMACH_SPI0_TX, DMACH_UART4_TX,
.rqtype = MEMTODEV, DMACH_SLIMBUS0_RX,
}, { DMACH_SLIMBUS0_TX,
.peri_id = (u8)DMACH_SPI2_RX, DMACH_SLIMBUS2_RX,
.rqtype = DEVTOMEM, DMACH_SLIMBUS2_TX,
}, { DMACH_SLIMBUS4_RX,
.peri_id = (u8)DMACH_SPI2_TX, DMACH_SLIMBUS4_TX,
.rqtype = MEMTODEV, DMACH_AC97_MICIN,
}, { DMACH_AC97_PCMIN,
.peri_id = (u8)DMACH_I2S0S_TX, DMACH_AC97_PCMOUT,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_I2S0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_UART0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_UART0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_UART2_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_UART2_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_UART4_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_UART4_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SLIMBUS0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SLIMBUS0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SLIMBUS2_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SLIMBUS2_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SLIMBUS4_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SLIMBUS4_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_AC97_MICIN,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_AC97_PCMIN,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_AC97_PCMOUT,
.rqtype = MEMTODEV,
},
}; };
struct dma_pl330_platdata exynos4_pdma0_pdata = { struct dma_pl330_platdata exynos4_pdma0_pdata = {
.nr_valid_peri = ARRAY_SIZE(pdma0_peri), .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
.peri = pdma0_peri, .peri_id = pdma0_peri,
}; };
struct amba_device exynos4_device_pdma0 = { struct amba_device exynos4_device_pdma0 = {
...@@ -142,86 +90,37 @@ struct amba_device exynos4_device_pdma0 = { ...@@ -142,86 +90,37 @@ struct amba_device exynos4_device_pdma0 = {
.periphid = 0x00041330, .periphid = 0x00041330,
}; };
struct dma_pl330_peri pdma1_peri[25] = { u8 pdma1_peri[] = {
{ DMACH_PCM0_RX,
.peri_id = (u8)DMACH_PCM0_RX, DMACH_PCM0_TX,
.rqtype = DEVTOMEM, DMACH_PCM1_RX,
}, { DMACH_PCM1_TX,
.peri_id = (u8)DMACH_PCM0_TX, DMACH_MSM_REQ1,
.rqtype = MEMTODEV, DMACH_MSM_REQ3,
}, { DMACH_SPI1_RX,
.peri_id = (u8)DMACH_PCM1_RX, DMACH_SPI1_TX,
.rqtype = DEVTOMEM, DMACH_I2S0S_TX,
}, { DMACH_I2S0_RX,
.peri_id = (u8)DMACH_PCM1_TX, DMACH_I2S0_TX,
.rqtype = MEMTODEV, DMACH_I2S1_RX,
}, { DMACH_I2S1_TX,
.peri_id = (u8)DMACH_MSM_REQ1, DMACH_UART0_RX,
}, { DMACH_UART0_TX,
.peri_id = (u8)DMACH_MSM_REQ3, DMACH_UART1_RX,
}, { DMACH_UART1_TX,
.peri_id = (u8)DMACH_SPI1_RX, DMACH_UART3_RX,
.rqtype = DEVTOMEM, DMACH_UART3_TX,
}, { DMACH_SLIMBUS1_RX,
.peri_id = (u8)DMACH_SPI1_TX, DMACH_SLIMBUS1_TX,
.rqtype = MEMTODEV, DMACH_SLIMBUS3_RX,
}, { DMACH_SLIMBUS3_TX,
.peri_id = (u8)DMACH_I2S0S_TX, DMACH_SLIMBUS5_RX,
.rqtype = MEMTODEV, DMACH_SLIMBUS5_TX,
}, {
.peri_id = (u8)DMACH_I2S0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_I2S0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_I2S1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_UART0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_UART0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_UART1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_UART1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_UART3_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_UART3_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SLIMBUS1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SLIMBUS1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SLIMBUS3_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SLIMBUS3_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SLIMBUS5_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SLIMBUS5_TX,
.rqtype = MEMTODEV,
},
}; };
struct dma_pl330_platdata exynos4_pdma1_pdata = { struct dma_pl330_platdata exynos4_pdma1_pdata = {
.nr_valid_peri = ARRAY_SIZE(pdma1_peri), .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
.peri = pdma1_peri, .peri_id = pdma1_peri,
}; };
struct amba_device exynos4_device_pdma1 = { struct amba_device exynos4_device_pdma1 = {
...@@ -242,7 +141,15 @@ struct amba_device exynos4_device_pdma1 = { ...@@ -242,7 +141,15 @@ struct amba_device exynos4_device_pdma1 = {
static int __init exynos4_dma_init(void) static int __init exynos4_dma_init(void)
{ {
if (of_have_populated_dt())
return 0;
dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask);
amba_device_register(&exynos4_device_pdma0, &iomem_resource); amba_device_register(&exynos4_device_pdma0, &iomem_resource);
dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask);
amba_device_register(&exynos4_device_pdma1, &iomem_resource); amba_device_register(&exynos4_device_pdma1, &iomem_resource);
return 0; return 0;
......
...@@ -17,13 +17,13 @@ ...@@ -17,13 +17,13 @@
/* PPI: Private Peripheral Interrupt */ /* PPI: Private Peripheral Interrupt */
#define IRQ_PPI(x) S5P_IRQ(x+16) #define IRQ_PPI(x) (x+16)
#define IRQ_MCT_LOCALTIMER IRQ_PPI(12) #define IRQ_MCT_LOCALTIMER IRQ_PPI(12)
/* SPI: Shared Peripheral Interrupt */ /* SPI: Shared Peripheral Interrupt */
#define IRQ_SPI(x) S5P_IRQ(x+32) #define IRQ_SPI(x) (x+32)
#define IRQ_EINT0 IRQ_SPI(16) #define IRQ_EINT0 IRQ_SPI(16)
#define IRQ_EINT1 IRQ_SPI(17) #define IRQ_EINT1 IRQ_SPI(17)
...@@ -163,7 +163,9 @@ ...@@ -163,7 +163,9 @@
#define IRQ_GPIO2_NR_GROUPS 9 #define IRQ_GPIO2_NR_GROUPS 9
#define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT) #define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
#define IRQ_TIMER_BASE (IRQ_GPIO_END + 64)
/* Set the default NR_IRQS */ /* Set the default NR_IRQS */
#define NR_IRQS (IRQ_GPIO_END + 64) #define NR_IRQS (IRQ_TIMER_BASE + IRQ_TIMER_COUNT)
#endif /* __ASM_ARCH_IRQS_H */ #endif /* __ASM_ARCH_IRQS_H */
/*
* Samsung's Exynos4210 flattened device tree enabled machine
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
* Copyright (c) 2010-2011 Linaro Ltd.
* www.linaro.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/of_platform.h>
#include <linux/serial_core.h>
#include <asm/mach/arch.h>
#include <mach/map.h>
#include <plat/cpu.h>
#include <plat/regs-serial.h>
#include <plat/exynos4.h>
/*
* The following lookup table is used to override device names when devices
* are registered from device tree. This is temporarily added to enable
* device tree support addition for the Exynos4 architecture.
*
* For drivers that require platform data to be provided from the machine
* file, a platform data pointer can also be supplied along with the
* devices names. Usually, the platform data elements that cannot be parsed
* from the device tree by the drivers (example: function pointers) are
* supplied. But it should be noted that this is a temporary mechanism and
* at some point, the drivers should be capable of parsing all the platform
* data from the device tree.
*/
static const struct of_dev_auxdata exynos4210_auxdata_lookup[] __initconst = {
OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART0,
"exynos4210-uart.0", NULL),
OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART1,
"exynos4210-uart.1", NULL),
OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART2,
"exynos4210-uart.2", NULL),
OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART3,
"exynos4210-uart.3", NULL),
OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(0),
"exynos4-sdhci.0", NULL),
OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(1),
"exynos4-sdhci.1", NULL),
OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(2),
"exynos4-sdhci.2", NULL),
OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(3),
"exynos4-sdhci.3", NULL),
OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(0),
"s3c2440-i2c.0", NULL),
OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL),
OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL),
{},
};
static void __init exynos4210_dt_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
s3c24xx_init_clocks(24000000);
}
static void __init exynos4210_dt_machine_init(void)
{
of_platform_populate(NULL, of_default_bus_match_table,
exynos4210_auxdata_lookup, NULL);
}
static char const *exynos4210_dt_compat[] __initdata = {
"samsung,exynos4210",
NULL
};
DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
/* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
.init_irq = exynos4_init_irq,
.map_io = exynos4210_dt_map_io,
.init_machine = exynos4210_dt_machine_init,
.timer = &exynos4_timer,
.dt_compat = exynos4210_dt_compat,
MACHINE_END
...@@ -165,22 +165,6 @@ static struct map_desc bast_iodesc[] __initdata = { ...@@ -165,22 +165,6 @@ static struct map_desc bast_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
static struct s3c24xx_uart_clksrc bast_serial_clocks[] = {
[0] = {
.name = "uclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
},
[1] = {
.name = "pclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
}
};
static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = { static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
[0] = { [0] = {
.hwport = 0, .hwport = 0,
...@@ -188,8 +172,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = { ...@@ -188,8 +172,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
.ucon = UCON, .ucon = UCON,
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = bast_serial_clocks,
.clocks_size = ARRAY_SIZE(bast_serial_clocks),
}, },
[1] = { [1] = {
.hwport = 1, .hwport = 1,
...@@ -197,8 +179,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = { ...@@ -197,8 +179,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
.ucon = UCON, .ucon = UCON,
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = bast_serial_clocks,
.clocks_size = ARRAY_SIZE(bast_serial_clocks),
}, },
/* port 2 is not actually used */ /* port 2 is not actually used */
[2] = { [2] = {
...@@ -207,8 +187,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = { ...@@ -207,8 +187,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
.ucon = UCON, .ucon = UCON,
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = bast_serial_clocks,
.clocks_size = ARRAY_SIZE(bast_serial_clocks),
} }
}; };
......
...@@ -110,23 +110,6 @@ static struct map_desc vr1000_iodesc[] __initdata = { ...@@ -110,23 +110,6 @@ static struct map_desc vr1000_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
/* uart clock source(s) */
static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = {
[0] = {
.name = "uclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
},
[1] = {
.name = "pclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0.
}
};
static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = { static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
[0] = { [0] = {
.hwport = 0, .hwport = 0,
...@@ -134,8 +117,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = { ...@@ -134,8 +117,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
.ucon = UCON, .ucon = UCON,
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = vr1000_serial_clocks,
.clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
}, },
[1] = { [1] = {
.hwport = 1, .hwport = 1,
...@@ -143,8 +124,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = { ...@@ -143,8 +124,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
.ucon = UCON, .ucon = UCON,
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = vr1000_serial_clocks,
.clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
}, },
/* port 2 is not actually used */ /* port 2 is not actually used */
[2] = { [2] = {
...@@ -153,9 +132,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = { ...@@ -153,9 +132,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
.ucon = UCON, .ucon = UCON,
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = vr1000_serial_clocks,
.clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
} }
}; };
......
...@@ -124,12 +124,18 @@ static struct clk s3c2410_armclk = { ...@@ -124,12 +124,18 @@ static struct clk s3c2410_armclk = {
.id = -1, .id = -1,
}; };
static struct clk_lookup s3c2410_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
};
void __init s3c2410_init_clocks(int xtal) void __init s3c2410_init_clocks(int xtal)
{ {
s3c24xx_register_baseclocks(xtal); s3c24xx_register_baseclocks(xtal);
s3c2410_setup_clocks(); s3c2410_setup_clocks();
s3c2410_baseclk_add(); s3c2410_baseclk_add();
s3c24xx_register_clock(&s3c2410_armclk); s3c24xx_register_clock(&s3c2410_armclk);
clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup));
} }
struct bus_type s3c2410_subsys = { struct bus_type s3c2410_subsys = {
......
...@@ -659,6 +659,12 @@ static struct clk *clks[] __initdata = { ...@@ -659,6 +659,12 @@ static struct clk *clks[] __initdata = {
&clk_armclk, &clk_armclk,
}; };
static struct clk_lookup s3c2412_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_usysclk),
};
int __init s3c2412_baseclk_add(void) int __init s3c2412_baseclk_add(void)
{ {
unsigned long clkcon = __raw_readl(S3C2410_CLKCON); unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
...@@ -751,6 +757,7 @@ int __init s3c2412_baseclk_add(void) ...@@ -751,6 +757,7 @@ int __init s3c2412_baseclk_add(void)
s3c2412_clkcon_enable(clkp, 0); s3c2412_clkcon_enable(clkp, 0);
} }
clkdev_add_table(s3c2412_clk_lookup, ARRAY_SIZE(s3c2412_clk_lookup));
s3c_pwmclk_init(); s3c_pwmclk_init();
return 0; return 0;
} }
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/serial_core.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <linux/atomic.h> #include <linux/atomic.h>
...@@ -42,6 +43,7 @@ ...@@ -42,6 +43,7 @@
#include <plat/clock.h> #include <plat/clock.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/regs-serial.h>
/* S3C2440 extended clock support */ /* S3C2440 extended clock support */
...@@ -107,6 +109,46 @@ static struct clk s3c2440_clk_ac97 = { ...@@ -107,6 +109,46 @@ static struct clk s3c2440_clk_ac97 = {
.ctrlbit = S3C2440_CLKCON_CAMERA, .ctrlbit = S3C2440_CLKCON_CAMERA,
}; };
static unsigned long s3c2440_fclk_n_getrate(struct clk *clk)
{
unsigned long ucon0, ucon1, ucon2, divisor;
/* the fun of calculating the uart divisors on the s3c2440 */
ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
ucon0 &= S3C2440_UCON0_DIVMASK;
ucon1 &= S3C2440_UCON1_DIVMASK;
ucon2 &= S3C2440_UCON2_DIVMASK;
if (ucon0 != 0)
divisor = (ucon0 >> S3C2440_UCON_DIVSHIFT) + 6;
else if (ucon1 != 0)
divisor = (ucon1 >> S3C2440_UCON_DIVSHIFT) + 21;
else if (ucon2 != 0)
divisor = (ucon2 >> S3C2440_UCON_DIVSHIFT) + 36;
else
/* manual calims 44, seems to be 9 */
divisor = 9;
return clk_get_rate(clk->parent) / divisor;
}
static struct clk s3c2440_clk_fclk_n = {
.name = "fclk_n",
.parent = &clk_f,
.ops = &(struct clk_ops) {
.get_rate = s3c2440_fclk_n_getrate,
},
};
static struct clk_lookup s3c2440_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n),
};
static int s3c2440_clk_add(struct device *dev) static int s3c2440_clk_add(struct device *dev)
{ {
struct clk *clock_upll; struct clk *clock_upll;
...@@ -125,10 +167,12 @@ static int s3c2440_clk_add(struct device *dev) ...@@ -125,10 +167,12 @@ static int s3c2440_clk_add(struct device *dev)
s3c2440_clk_cam.parent = clock_h; s3c2440_clk_cam.parent = clock_h;
s3c2440_clk_ac97.parent = clock_p; s3c2440_clk_ac97.parent = clock_p;
s3c2440_clk_cam_upll.parent = clock_upll; s3c2440_clk_cam_upll.parent = clock_upll;
s3c24xx_register_clock(&s3c2440_clk_fclk_n);
s3c24xx_register_clock(&s3c2440_clk_ac97); s3c24xx_register_clock(&s3c2440_clk_ac97);
s3c24xx_register_clock(&s3c2440_clk_cam); s3c24xx_register_clock(&s3c2440_clk_cam);
s3c24xx_register_clock(&s3c2440_clk_cam_upll); s3c24xx_register_clock(&s3c2440_clk_cam_upll);
clkdev_add_table(s3c2440_clk_lookup, ARRAY_SIZE(s3c2440_clk_lookup));
clk_disable(&s3c2440_clk_ac97); clk_disable(&s3c2440_clk_ac97);
clk_disable(&s3c2440_clk_cam); clk_disable(&s3c2440_clk_cam);
......
...@@ -98,22 +98,6 @@ static struct map_desc anubis_iodesc[] __initdata = { ...@@ -98,22 +98,6 @@ static struct map_desc anubis_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = {
[0] = {
.name = "uclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
},
[1] = {
.name = "pclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
}
};
static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = { static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
[0] = { [0] = {
.hwport = 0, .hwport = 0,
...@@ -121,8 +105,7 @@ static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = { ...@@ -121,8 +105,7 @@ static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
.ucon = UCON, .ucon = UCON,
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = anubis_serial_clocks, .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
.clocks_size = ARRAY_SIZE(anubis_serial_clocks),
}, },
[1] = { [1] = {
.hwport = 2, .hwport = 2,
...@@ -130,8 +113,7 @@ static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = { ...@@ -130,8 +113,7 @@ static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
.ucon = UCON, .ucon = UCON,
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = anubis_serial_clocks, .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
.clocks_size = ARRAY_SIZE(anubis_serial_clocks),
}, },
}; };
......
...@@ -59,22 +59,6 @@ static struct map_desc at2440evb_iodesc[] __initdata = { ...@@ -59,22 +59,6 @@ static struct map_desc at2440evb_iodesc[] __initdata = {
#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE) #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
static struct s3c24xx_uart_clksrc at2440evb_serial_clocks[] = {
[0] = {
.name = "uclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
},
[1] = {
.name = "pclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
}
};
static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = { static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
[0] = { [0] = {
.hwport = 0, .hwport = 0,
...@@ -82,8 +66,7 @@ static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = { ...@@ -82,8 +66,7 @@ static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
.ucon = UCON, .ucon = UCON,
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = at2440evb_serial_clocks, .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
.clocks_size = ARRAY_SIZE(at2440evb_serial_clocks),
}, },
[1] = { [1] = {
.hwport = 1, .hwport = 1,
...@@ -91,8 +74,7 @@ static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = { ...@@ -91,8 +74,7 @@ static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
.ucon = UCON, .ucon = UCON,
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = at2440evb_serial_clocks, .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
.clocks_size = ARRAY_SIZE(at2440evb_serial_clocks),
}, },
}; };
......
...@@ -102,21 +102,6 @@ static struct map_desc osiris_iodesc[] __initdata = { ...@@ -102,21 +102,6 @@ static struct map_desc osiris_iodesc[] __initdata = {
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
static struct s3c24xx_uart_clksrc osiris_serial_clocks[] = {
[0] = {
.name = "uclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
},
[1] = {
.name = "pclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
}
};
static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = { static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
[0] = { [0] = {
.hwport = 0, .hwport = 0,
...@@ -124,8 +109,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = { ...@@ -124,8 +109,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
.ucon = UCON, .ucon = UCON,
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = osiris_serial_clocks, .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
.clocks_size = ARRAY_SIZE(osiris_serial_clocks),
}, },
[1] = { [1] = {
.hwport = 1, .hwport = 1,
...@@ -133,8 +117,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = { ...@@ -133,8 +117,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
.ucon = UCON, .ucon = UCON,
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = osiris_serial_clocks, .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
.clocks_size = ARRAY_SIZE(osiris_serial_clocks),
}, },
[2] = { [2] = {
.hwport = 2, .hwport = 2,
...@@ -142,8 +125,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = { ...@@ -142,8 +125,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
.ucon = UCON, .ucon = UCON,
.ulcon = ULCON, .ulcon = ULCON,
.ufcon = UFCON, .ufcon = UFCON,
.clocks = osiris_serial_clocks, .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
.clocks_size = ARRAY_SIZE(osiris_serial_clocks),
} }
}; };
......
...@@ -70,15 +70,6 @@ ...@@ -70,15 +70,6 @@
static struct map_desc rx1950_iodesc[] __initdata = { static struct map_desc rx1950_iodesc[] __initdata = {
}; };
static struct s3c24xx_uart_clksrc rx1950_serial_clocks[] = {
[0] = {
.name = "fclk",
.divisor = 0x0a,
.min_baud = 0,
.max_baud = 0,
},
};
static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = { static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
[0] = { [0] = {
.hwport = 0, .hwport = 0,
...@@ -86,8 +77,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = { ...@@ -86,8 +77,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
.ucon = 0x3c5, .ucon = 0x3c5,
.ulcon = 0x03, .ulcon = 0x03,
.ufcon = 0x51, .ufcon = 0x51,
.clocks = rx1950_serial_clocks, .clk_sel = S3C2410_UCON_CLKSEL3,
.clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
}, },
[1] = { [1] = {
.hwport = 1, .hwport = 1,
...@@ -95,8 +85,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = { ...@@ -95,8 +85,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
.ucon = 0x3c5, .ucon = 0x3c5,
.ulcon = 0x03, .ulcon = 0x03,
.ufcon = 0x51, .ufcon = 0x51,
.clocks = rx1950_serial_clocks, .clk_sel = S3C2410_UCON_CLKSEL3,
.clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
}, },
/* IR port */ /* IR port */
[2] = { [2] = {
...@@ -105,8 +94,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = { ...@@ -105,8 +94,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
.ucon = 0x3c5, .ucon = 0x3c5,
.ulcon = 0x43, .ulcon = 0x43,
.ufcon = 0xf1, .ufcon = 0xf1,
.clocks = rx1950_serial_clocks, .clk_sel = S3C2410_UCON_CLKSEL3,
.clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
}, },
}; };
......
...@@ -69,16 +69,6 @@ static struct map_desc rx3715_iodesc[] __initdata = { ...@@ -69,16 +69,6 @@ static struct map_desc rx3715_iodesc[] __initdata = {
}, },
}; };
static struct s3c24xx_uart_clksrc rx3715_serial_clocks[] = {
[0] = {
.name = "fclk",
.divisor = 0,
.min_baud = 0,
.max_baud = 0,
}
};
static struct s3c2410_uartcfg rx3715_uartcfgs[] = { static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
[0] = { [0] = {
.hwport = 0, .hwport = 0,
...@@ -86,8 +76,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = { ...@@ -86,8 +76,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
.ucon = 0x3c5, .ucon = 0x3c5,
.ulcon = 0x03, .ulcon = 0x03,
.ufcon = 0x51, .ufcon = 0x51,
.clocks = rx3715_serial_clocks, .clk_sel = S3C2410_UCON_CLKSEL3,
.clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
}, },
[1] = { [1] = {
.hwport = 1, .hwport = 1,
...@@ -95,8 +84,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = { ...@@ -95,8 +84,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
.ucon = 0x3c5, .ucon = 0x3c5,
.ulcon = 0x03, .ulcon = 0x03,
.ufcon = 0x00, .ufcon = 0x00,
.clocks = rx3715_serial_clocks, .clk_sel = S3C2410_UCON_CLKSEL3,
.clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
}, },
/* IR port */ /* IR port */
[2] = { [2] = {
...@@ -105,8 +93,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = { ...@@ -105,8 +93,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
.ucon = 0x3c5, .ucon = 0x3c5,
.ulcon = 0x43, .ulcon = 0x43,
.ufcon = 0x51, .ufcon = 0x51,
.clocks = rx3715_serial_clocks, .clk_sel = S3C2410_UCON_CLKSEL3,
.clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
} }
}; };
......
...@@ -616,16 +616,6 @@ static struct clksrc_clk clksrcs[] = { ...@@ -616,16 +616,6 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S3C_CLK_DIV1, .shift = 20, .size = 4 }, .reg_div = { .reg = S3C_CLK_DIV1, .shift = 20, .size = 4 },
.sources = &clkset_uhost, .sources = &clkset_uhost,
}, { }, {
.clk = {
.name = "uclk1",
.ctrlbit = S3C_CLKCON_SCLK_UART,
.enable = s3c64xx_sclk_ctrl,
},
.reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 },
.reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 },
.sources = &clkset_uart,
}, {
/* Where does UCLK0 come from? */
.clk = { .clk = {
.name = "spi-bus", .name = "spi-bus",
.devname = "s3c64xx-spi.0", .devname = "s3c64xx-spi.0",
...@@ -695,6 +685,18 @@ static struct clksrc_clk clksrcs[] = { ...@@ -695,6 +685,18 @@ static struct clksrc_clk clksrcs[] = {
}, },
}; };
/* Where does UCLK0 come from? */
static struct clksrc_clk clk_sclk_uclk = {
.clk = {
.name = "uclk1",
.ctrlbit = S3C_CLKCON_SCLK_UART,
.enable = s3c64xx_sclk_ctrl,
},
.reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 },
.reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 },
.sources = &clkset_uart,
};
/* Clock initialisation code */ /* Clock initialisation code */
static struct clksrc_clk *init_parents[] = { static struct clksrc_clk *init_parents[] = {
...@@ -703,6 +705,15 @@ static struct clksrc_clk *init_parents[] = { ...@@ -703,6 +705,15 @@ static struct clksrc_clk *init_parents[] = {
&clk_mout_mpll, &clk_mout_mpll,
}; };
static struct clksrc_clk *clksrc_cdev[] = {
&clk_sclk_uclk,
};
static struct clk_lookup s3c64xx_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
};
#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
void __init_or_cpufreq s3c64xx_setup_clocks(void) void __init_or_cpufreq s3c64xx_setup_clocks(void)
...@@ -811,6 +822,8 @@ static struct clk *clks[] __initdata = { ...@@ -811,6 +822,8 @@ static struct clk *clks[] __initdata = {
void __init s3c64xx_register_clocks(unsigned long xtal, void __init s3c64xx_register_clocks(unsigned long xtal,
unsigned armclk_divlimit) unsigned armclk_divlimit)
{ {
unsigned int cnt;
armclk_mask = armclk_divlimit; armclk_mask = armclk_divlimit;
s3c24xx_register_baseclocks(xtal); s3c24xx_register_baseclocks(xtal);
...@@ -823,5 +836,9 @@ void __init s3c64xx_register_clocks(unsigned long xtal, ...@@ -823,5 +836,9 @@ void __init s3c64xx_register_clocks(unsigned long xtal,
s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1)); s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1));
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
for (cnt = 0; cnt < ARRAY_SIZE(clksrc_cdev); cnt++)
s3c_register_clksrc(clksrc_cdev[cnt], 1);
clkdev_add_table(s3c64xx_clk_lookup, ARRAY_SIZE(s3c64xx_clk_lookup));
s3c_pwmclk_init(); s3c_pwmclk_init();
} }
...@@ -420,15 +420,6 @@ static struct clksrc_clk clksrcs[] = { ...@@ -420,15 +420,6 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_group1, .sources = &clkset_group1,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 }, .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
.reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
}, {
.clk = {
.name = "uclk1",
.ctrlbit = (1 << 5),
.enable = s5p64x0_sclk_ctrl,
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
.reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
}, { }, {
.clk = { .clk = {
.name = "sclk_spi", .name = "sclk_spi",
...@@ -488,6 +479,17 @@ static struct clksrc_clk clksrcs[] = { ...@@ -488,6 +479,17 @@ static struct clksrc_clk clksrcs[] = {
}, },
}; };
static struct clksrc_clk clk_sclk_uclk = {
.clk = {
.name = "uclk1",
.ctrlbit = (1 << 5),
.enable = s5p64x0_sclk_ctrl,
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
.reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
};
/* Clock initialization code */ /* Clock initialization code */
static struct clksrc_clk *sysclks[] = { static struct clksrc_clk *sysclks[] = {
&clk_mout_apll, &clk_mout_apll,
...@@ -506,6 +508,15 @@ static struct clk dummy_apb_pclk = { ...@@ -506,6 +508,15 @@ static struct clk dummy_apb_pclk = {
.id = -1, .id = -1,
}; };
static struct clksrc_clk *clksrc_cdev[] = {
&clk_sclk_uclk,
};
static struct clk_lookup s5p6440_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
};
void __init_or_cpufreq s5p6440_setup_clocks(void) void __init_or_cpufreq s5p6440_setup_clocks(void)
{ {
struct clk *xtal_clk; struct clk *xtal_clk;
...@@ -584,9 +595,12 @@ void __init s5p6440_register_clocks(void) ...@@ -584,9 +595,12 @@ void __init s5p6440_register_clocks(void)
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
s3c_register_clksrc(clksrc_cdev[ptr], 1);
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
clkdev_add_table(s5p6440_clk_lookup, ARRAY_SIZE(s5p6440_clk_lookup));
s3c24xx_register_clock(&dummy_apb_pclk); s3c24xx_register_clock(&dummy_apb_pclk);
......
...@@ -442,15 +442,6 @@ static struct clksrc_clk clksrcs[] = { ...@@ -442,15 +442,6 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_group2, .sources = &clkset_group2,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 }, .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
.reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
}, {
.clk = {
.name = "uclk1",
.ctrlbit = (1 << 5),
.enable = s5p64x0_sclk_ctrl,
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
.reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
}, { }, {
.clk = { .clk = {
.name = "sclk_spi", .name = "sclk_spi",
...@@ -537,6 +528,26 @@ static struct clksrc_clk clksrcs[] = { ...@@ -537,6 +528,26 @@ static struct clksrc_clk clksrcs[] = {
}, },
}; };
static struct clksrc_clk clk_sclk_uclk = {
.clk = {
.name = "uclk1",
.ctrlbit = (1 << 5),
.enable = s5p64x0_sclk_ctrl,
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
.reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
};
static struct clksrc_clk *clksrc_cdev[] = {
&clk_sclk_uclk,
};
static struct clk_lookup s5p6450_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
};
/* Clock initialization code */ /* Clock initialization code */
static struct clksrc_clk *sysclks[] = { static struct clksrc_clk *sysclks[] = {
&clk_mout_apll, &clk_mout_apll,
...@@ -635,9 +646,12 @@ void __init s5p6450_register_clocks(void) ...@@ -635,9 +646,12 @@ void __init s5p6450_register_clocks(void)
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
s3c_register_clksrc(clksrc_cdev[ptr], 1);
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
clkdev_add_table(s5p6450_clk_lookup, ARRAY_SIZE(s5p6450_clk_lookup));
s3c24xx_register_clock(&dummy_apb_pclk); s3c24xx_register_clock(&dummy_apb_pclk);
......
...@@ -282,36 +282,7 @@ int __init s5p64x0_init(void) ...@@ -282,36 +282,7 @@ int __init s5p64x0_init(void)
return device_register(&s5p64x0_dev); return device_register(&s5p64x0_dev);
} }
static struct s3c24xx_uart_clksrc s5p64x0_serial_clocks[] = {
[0] = {
.name = "pclk_low",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
},
[1] = {
.name = "uclk1",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
},
};
/* uart registration process */ /* uart registration process */
void __init s5p64x0_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
struct s3c2410_uartcfg *tcfg = cfg;
u32 ucnt;
for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
if (!tcfg->clocks) {
tcfg->clocks = s5p64x0_serial_clocks;
tcfg->clocks_size = ARRAY_SIZE(s5p64x0_serial_clocks);
}
}
}
void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no) void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{ {
int uart; int uart;
...@@ -321,13 +292,11 @@ void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no) ...@@ -321,13 +292,11 @@ void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART; s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART;
} }
s5p64x0_common_init_uarts(cfg, no);
s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
} }
void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no) void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{ {
s5p64x0_common_init_uarts(cfg, no);
s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
} }
......
...@@ -38,176 +38,74 @@ ...@@ -38,176 +38,74 @@
static u64 dma_dmamask = DMA_BIT_MASK(32); static u64 dma_dmamask = DMA_BIT_MASK(32);
struct dma_pl330_peri s5p6440_pdma_peri[22] = { u8 s5p6440_pdma_peri[] = {
{ DMACH_UART0_RX,
.peri_id = (u8)DMACH_UART0_RX, DMACH_UART0_TX,
.rqtype = DEVTOMEM, DMACH_UART1_RX,
}, { DMACH_UART1_TX,
.peri_id = (u8)DMACH_UART0_TX, DMACH_UART2_RX,
.rqtype = MEMTODEV, DMACH_UART2_TX,
}, { DMACH_UART3_RX,
.peri_id = (u8)DMACH_UART1_RX, DMACH_UART3_TX,
.rqtype = DEVTOMEM, DMACH_MAX,
}, { DMACH_MAX,
.peri_id = (u8)DMACH_UART1_TX, DMACH_PCM0_TX,
.rqtype = MEMTODEV, DMACH_PCM0_RX,
}, { DMACH_I2S0_TX,
.peri_id = (u8)DMACH_UART2_RX, DMACH_I2S0_RX,
.rqtype = DEVTOMEM, DMACH_SPI0_TX,
}, { DMACH_SPI0_RX,
.peri_id = (u8)DMACH_UART2_TX, DMACH_MAX,
.rqtype = MEMTODEV, DMACH_MAX,
}, { DMACH_MAX,
.peri_id = (u8)DMACH_UART3_RX, DMACH_MAX,
.rqtype = DEVTOMEM, DMACH_SPI1_TX,
}, { DMACH_SPI1_RX,
.peri_id = (u8)DMACH_UART3_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = DMACH_MAX,
}, {
.peri_id = DMACH_MAX,
}, {
.peri_id = (u8)DMACH_PCM0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_PCM0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_I2S0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SPI0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SPI0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_MAX,
}, {
.peri_id = (u8)DMACH_MAX,
}, {
.peri_id = (u8)DMACH_MAX,
}, {
.peri_id = (u8)DMACH_MAX,
}, {
.peri_id = (u8)DMACH_SPI1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SPI1_RX,
.rqtype = DEVTOMEM,
},
}; };
struct dma_pl330_platdata s5p6440_pdma_pdata = { struct dma_pl330_platdata s5p6440_pdma_pdata = {
.nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri), .nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri),
.peri = s5p6440_pdma_peri, .peri_id = s5p6440_pdma_peri,
}; };
struct dma_pl330_peri s5p6450_pdma_peri[32] = { u8 s5p6450_pdma_peri[] = {
{ DMACH_UART0_RX,
.peri_id = (u8)DMACH_UART0_RX, DMACH_UART0_TX,
.rqtype = DEVTOMEM, DMACH_UART1_RX,
}, { DMACH_UART1_TX,
.peri_id = (u8)DMACH_UART0_TX, DMACH_UART2_RX,
.rqtype = MEMTODEV, DMACH_UART2_TX,
}, { DMACH_UART3_RX,
.peri_id = (u8)DMACH_UART1_RX, DMACH_UART3_TX,
.rqtype = DEVTOMEM, DMACH_UART4_RX,
}, { DMACH_UART4_TX,
.peri_id = (u8)DMACH_UART1_TX, DMACH_PCM0_TX,
.rqtype = MEMTODEV, DMACH_PCM0_RX,
}, { DMACH_I2S0_TX,
.peri_id = (u8)DMACH_UART2_RX, DMACH_I2S0_RX,
.rqtype = DEVTOMEM, DMACH_SPI0_TX,
}, { DMACH_SPI0_RX,
.peri_id = (u8)DMACH_UART2_TX, DMACH_PCM1_TX,
.rqtype = MEMTODEV, DMACH_PCM1_RX,
}, { DMACH_PCM2_TX,
.peri_id = (u8)DMACH_UART3_RX, DMACH_PCM2_RX,
.rqtype = DEVTOMEM, DMACH_SPI1_TX,
}, { DMACH_SPI1_RX,
.peri_id = (u8)DMACH_UART3_TX, DMACH_USI_TX,
.rqtype = MEMTODEV, DMACH_USI_RX,
}, { DMACH_MAX,
.peri_id = (u8)DMACH_UART4_RX, DMACH_I2S1_TX,
.rqtype = DEVTOMEM, DMACH_I2S1_RX,
}, { DMACH_I2S2_TX,
.peri_id = (u8)DMACH_UART4_TX, DMACH_I2S2_RX,
.rqtype = MEMTODEV, DMACH_PWM,
}, { DMACH_UART5_RX,
.peri_id = (u8)DMACH_PCM0_TX, DMACH_UART5_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_PCM0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_I2S0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SPI0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SPI0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_PCM1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_PCM1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_PCM2_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_PCM2_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SPI1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SPI1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_USI_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_USI_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_MAX,
}, {
.peri_id = (u8)DMACH_I2S1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_I2S2_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S2_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_PWM,
}, {
.peri_id = (u8)DMACH_UART5_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_UART5_TX,
.rqtype = MEMTODEV,
},
}; };
struct dma_pl330_platdata s5p6450_pdma_pdata = { struct dma_pl330_platdata s5p6450_pdma_pdata = {
.nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri), .nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri),
.peri = s5p6450_pdma_peri, .peri_id = s5p6450_pdma_peri,
}; };
struct amba_device s5p64x0_device_pdma = { struct amba_device s5p64x0_device_pdma = {
...@@ -227,10 +125,15 @@ struct amba_device s5p64x0_device_pdma = { ...@@ -227,10 +125,15 @@ struct amba_device s5p64x0_device_pdma = {
static int __init s5p64x0_dma_init(void) static int __init s5p64x0_dma_init(void)
{ {
if (soc_is_s5p6450()) if (soc_is_s5p6450()) {
dma_cap_set(DMA_SLAVE, s5p6450_pdma_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, s5p6450_pdma_pdata.cap_mask);
s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata; s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata;
else } else {
dma_cap_set(DMA_SLAVE, s5p6440_pdma_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, s5p6440_pdma_pdata.cap_mask);
s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata; s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata;
}
amba_device_register(&s5p64x0_device_pdma, &iomem_resource); amba_device_register(&s5p64x0_device_pdma, &iomem_resource);
......
...@@ -141,6 +141,8 @@ ...@@ -141,6 +141,8 @@
#define IRQ_EINT_GROUP(grp, x) (IRQ_EINT_GROUP##grp##_BASE + (x)) #define IRQ_EINT_GROUP(grp, x) (IRQ_EINT_GROUP##grp##_BASE + (x))
#define IRQ_TIMER_BASE (11)
/* Set the default NR_IRQS */ /* Set the default NR_IRQS */
#define NR_IRQS (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1) #define NR_IRQS (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1)
......
...@@ -961,16 +961,6 @@ static struct clksrc_clk clksrcs[] = { ...@@ -961,16 +961,6 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clk_src_group1, .sources = &clk_src_group1,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 2 }, .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 2 },
.reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 }, .reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 },
}, {
.clk = {
.name = "uclk1",
.ctrlbit = (1 << 3),
.enable = s5pc100_sclk0_ctrl,
},
.sources = &clk_src_group2,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
.reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
}, { }, {
.clk = { .clk = {
.name = "sclk_mixer", .name = "sclk_mixer",
...@@ -1099,6 +1089,17 @@ static struct clksrc_clk clksrcs[] = { ...@@ -1099,6 +1089,17 @@ static struct clksrc_clk clksrcs[] = {
}, },
}; };
static struct clksrc_clk clk_sclk_uart = {
.clk = {
.name = "uclk1",
.ctrlbit = (1 << 3),
.enable = s5pc100_sclk0_ctrl,
},
.sources = &clk_src_group2,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
.reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
};
/* Clock initialisation code */ /* Clock initialisation code */
static struct clksrc_clk *sysclks[] = { static struct clksrc_clk *sysclks[] = {
&clk_mout_apll, &clk_mout_apll,
...@@ -1128,6 +1129,10 @@ static struct clksrc_clk *sysclks[] = { ...@@ -1128,6 +1129,10 @@ static struct clksrc_clk *sysclks[] = {
&clk_sclk_spdif, &clk_sclk_spdif,
}; };
static struct clksrc_clk *clksrc_cdev[] = {
&clk_sclk_uart,
};
void __init_or_cpufreq s5pc100_setup_clocks(void) void __init_or_cpufreq s5pc100_setup_clocks(void)
{ {
unsigned long xtal; unsigned long xtal;
...@@ -1267,6 +1272,11 @@ static struct clk *clks[] __initdata = { ...@@ -1267,6 +1272,11 @@ static struct clk *clks[] __initdata = {
&clk_pcmcdclk1, &clk_pcmcdclk1,
}; };
static struct clk_lookup s5pc100_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uart.clk),
};
void __init s5pc100_register_clocks(void) void __init s5pc100_register_clocks(void)
{ {
int ptr; int ptr;
...@@ -1278,9 +1288,12 @@ void __init s5pc100_register_clocks(void) ...@@ -1278,9 +1288,12 @@ void __init s5pc100_register_clocks(void)
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
s3c_register_clksrc(clksrc_cdev[ptr], 1);
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
clkdev_add_table(s5pc100_clk_lookup, ARRAY_SIZE(s5pc100_clk_lookup));
s3c24xx_register_clock(&dummy_apb_pclk); s3c24xx_register_clock(&dummy_apb_pclk);
......
...@@ -35,100 +35,42 @@ ...@@ -35,100 +35,42 @@
static u64 dma_dmamask = DMA_BIT_MASK(32); static u64 dma_dmamask = DMA_BIT_MASK(32);
struct dma_pl330_peri pdma0_peri[30] = { u8 pdma0_peri[] = {
{ DMACH_UART0_RX,
.peri_id = (u8)DMACH_UART0_RX, DMACH_UART0_TX,
.rqtype = DEVTOMEM, DMACH_UART1_RX,
}, { DMACH_UART1_TX,
.peri_id = (u8)DMACH_UART0_TX, DMACH_UART2_RX,
.rqtype = MEMTODEV, DMACH_UART2_TX,
}, { DMACH_UART3_RX,
.peri_id = (u8)DMACH_UART1_RX, DMACH_UART3_TX,
.rqtype = DEVTOMEM, DMACH_IRDA,
}, { DMACH_I2S0_RX,
.peri_id = (u8)DMACH_UART1_TX, DMACH_I2S0_TX,
.rqtype = MEMTODEV, DMACH_I2S0S_TX,
}, { DMACH_I2S1_RX,
.peri_id = (u8)DMACH_UART2_RX, DMACH_I2S1_TX,
.rqtype = DEVTOMEM, DMACH_I2S2_RX,
}, { DMACH_I2S2_TX,
.peri_id = (u8)DMACH_UART2_TX, DMACH_SPI0_RX,
.rqtype = MEMTODEV, DMACH_SPI0_TX,
}, { DMACH_SPI1_RX,
.peri_id = (u8)DMACH_UART3_RX, DMACH_SPI1_TX,
.rqtype = DEVTOMEM, DMACH_SPI2_RX,
}, { DMACH_SPI2_TX,
.peri_id = (u8)DMACH_UART3_TX, DMACH_AC97_MICIN,
.rqtype = MEMTODEV, DMACH_AC97_PCMIN,
}, { DMACH_AC97_PCMOUT,
.peri_id = DMACH_IRDA, DMACH_EXTERNAL,
}, { DMACH_PWM,
.peri_id = (u8)DMACH_I2S0_RX, DMACH_SPDIF,
.rqtype = DEVTOMEM, DMACH_HSI_RX,
}, { DMACH_HSI_TX,
.peri_id = (u8)DMACH_I2S0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S0S_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_I2S1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S2_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_I2S2_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SPI0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SPI0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SPI1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SPI1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SPI2_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SPI2_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_AC97_MICIN,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_AC97_PCMIN,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_AC97_PCMOUT,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_EXTERNAL,
}, {
.peri_id = (u8)DMACH_PWM,
}, {
.peri_id = (u8)DMACH_SPDIF,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_HSI_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_HSI_TX,
.rqtype = MEMTODEV,
},
}; };
struct dma_pl330_platdata s5pc100_pdma0_pdata = { struct dma_pl330_platdata s5pc100_pdma0_pdata = {
.nr_valid_peri = ARRAY_SIZE(pdma0_peri), .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
.peri = pdma0_peri, .peri_id = pdma0_peri,
}; };
struct amba_device s5pc100_device_pdma0 = { struct amba_device s5pc100_device_pdma0 = {
...@@ -147,98 +89,42 @@ struct amba_device s5pc100_device_pdma0 = { ...@@ -147,98 +89,42 @@ struct amba_device s5pc100_device_pdma0 = {
.periphid = 0x00041330, .periphid = 0x00041330,
}; };
struct dma_pl330_peri pdma1_peri[30] = { u8 pdma1_peri[] = {
{ DMACH_UART0_RX,
.peri_id = (u8)DMACH_UART0_RX, DMACH_UART0_TX,
.rqtype = DEVTOMEM, DMACH_UART1_RX,
}, { DMACH_UART1_TX,
.peri_id = (u8)DMACH_UART0_TX, DMACH_UART2_RX,
.rqtype = MEMTODEV, DMACH_UART2_TX,
}, { DMACH_UART3_RX,
.peri_id = (u8)DMACH_UART1_RX, DMACH_UART3_TX,
.rqtype = DEVTOMEM, DMACH_IRDA,
}, { DMACH_I2S0_RX,
.peri_id = (u8)DMACH_UART1_TX, DMACH_I2S0_TX,
.rqtype = MEMTODEV, DMACH_I2S0S_TX,
}, { DMACH_I2S1_RX,
.peri_id = (u8)DMACH_UART2_RX, DMACH_I2S1_TX,
.rqtype = DEVTOMEM, DMACH_I2S2_RX,
}, { DMACH_I2S2_TX,
.peri_id = (u8)DMACH_UART2_TX, DMACH_SPI0_RX,
.rqtype = MEMTODEV, DMACH_SPI0_TX,
}, { DMACH_SPI1_RX,
.peri_id = (u8)DMACH_UART3_RX, DMACH_SPI1_TX,
.rqtype = DEVTOMEM, DMACH_SPI2_RX,
}, { DMACH_SPI2_TX,
.peri_id = (u8)DMACH_UART3_TX, DMACH_PCM0_RX,
.rqtype = MEMTODEV, DMACH_PCM0_TX,
}, { DMACH_PCM1_RX,
.peri_id = DMACH_IRDA, DMACH_PCM1_TX,
}, { DMACH_MSM_REQ0,
.peri_id = (u8)DMACH_I2S0_RX, DMACH_MSM_REQ1,
.rqtype = DEVTOMEM, DMACH_MSM_REQ2,
}, { DMACH_MSM_REQ3,
.peri_id = (u8)DMACH_I2S0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S0S_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_I2S1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S2_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_I2S2_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SPI0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SPI0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SPI1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SPI1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SPI2_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SPI2_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_PCM0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_PCM1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_PCM1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_PCM1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_MSM_REQ0,
}, {
.peri_id = (u8)DMACH_MSM_REQ1,
}, {
.peri_id = (u8)DMACH_MSM_REQ2,
}, {
.peri_id = (u8)DMACH_MSM_REQ3,
},
}; };
struct dma_pl330_platdata s5pc100_pdma1_pdata = { struct dma_pl330_platdata s5pc100_pdma1_pdata = {
.nr_valid_peri = ARRAY_SIZE(pdma1_peri), .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
.peri = pdma1_peri, .peri_id = pdma1_peri,
}; };
struct amba_device s5pc100_device_pdma1 = { struct amba_device s5pc100_device_pdma1 = {
...@@ -259,7 +145,12 @@ struct amba_device s5pc100_device_pdma1 = { ...@@ -259,7 +145,12 @@ struct amba_device s5pc100_device_pdma1 = {
static int __init s5pc100_dma_init(void) static int __init s5pc100_dma_init(void)
{ {
dma_cap_set(DMA_SLAVE, s5pc100_pdma0_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, s5pc100_pdma0_pdata.cap_mask);
amba_device_register(&s5pc100_device_pdma0, &iomem_resource); amba_device_register(&s5pc100_device_pdma0, &iomem_resource);
dma_cap_set(DMA_SLAVE, s5pc100_pdma1_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, s5pc100_pdma1_pdata.cap_mask);
amba_device_register(&s5pc100_device_pdma1, &iomem_resource); amba_device_register(&s5pc100_device_pdma1, &iomem_resource);
return 0; return 0;
......
...@@ -97,6 +97,8 @@ ...@@ -97,6 +97,8 @@
#define IRQ_SDMFIQ S5P_IRQ_VIC2(31) #define IRQ_SDMFIQ S5P_IRQ_VIC2(31)
#define IRQ_VIC_END S5P_IRQ_VIC2(31) #define IRQ_VIC_END S5P_IRQ_VIC2(31)
#define IRQ_TIMER_BASE (11)
#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
#define S5P_EINT_BASE2 (IRQ_VIC_END + 1) #define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
......
...@@ -808,46 +808,6 @@ static struct clksrc_clk clksrcs[] = { ...@@ -808,46 +808,6 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_sclk_onenand, .sources = &clkset_sclk_onenand,
.reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 }, .reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 },
.reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 }, .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
}, {
.clk = {
.name = "uclk1",
.devname = "s5pv210-uart.0",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 12),
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
}, {
.clk = {
.name = "uclk1",
.devname = "s5pv210-uart.1",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 13),
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
}, {
.clk = {
.name = "uclk1",
.devname = "s5pv210-uart.2",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 14),
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
}, {
.clk = {
.name = "uclk1",
.devname = "s5pv210-uart.3",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 15),
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
}, { }, {
.clk = { .clk = {
.name = "sclk_fimc", .name = "sclk_fimc",
...@@ -1023,6 +983,61 @@ static struct clksrc_clk clksrcs[] = { ...@@ -1023,6 +983,61 @@ static struct clksrc_clk clksrcs[] = {
}, },
}; };
static struct clksrc_clk clk_sclk_uart0 = {
.clk = {
.name = "uclk1",
.devname = "s5pv210-uart.0",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 12),
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
};
static struct clksrc_clk clk_sclk_uart1 = {
.clk = {
.name = "uclk1",
.devname = "s5pv210-uart.1",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 13),
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
};
static struct clksrc_clk clk_sclk_uart2 = {
.clk = {
.name = "uclk1",
.devname = "s5pv210-uart.2",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 14),
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
};
static struct clksrc_clk clk_sclk_uart3 = {
.clk = {
.name = "uclk1",
.devname = "s5pv210-uart.3",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 15),
},
.sources = &clkset_uart,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
};
static struct clksrc_clk *clksrc_cdev[] = {
&clk_sclk_uart0,
&clk_sclk_uart1,
&clk_sclk_uart2,
&clk_sclk_uart3,
};
/* Clock initialisation code */ /* Clock initialisation code */
static struct clksrc_clk *sysclks[] = { static struct clksrc_clk *sysclks[] = {
&clk_mout_apll, &clk_mout_apll,
...@@ -1262,6 +1277,14 @@ static struct clk *clks[] __initdata = { ...@@ -1262,6 +1277,14 @@ static struct clk *clks[] __initdata = {
&clk_pcmcdclk2, &clk_pcmcdclk2,
}; };
static struct clk_lookup s5pv210_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
CLKDEV_INIT("s5pv210-uart.0", "clk_uart_baud1", &clk_sclk_uart0.clk),
CLKDEV_INIT("s5pv210-uart.1", "clk_uart_baud1", &clk_sclk_uart1.clk),
CLKDEV_INIT("s5pv210-uart.2", "clk_uart_baud1", &clk_sclk_uart2.clk),
CLKDEV_INIT("s5pv210-uart.3", "clk_uart_baud1", &clk_sclk_uart3.clk),
};
void __init s5pv210_register_clocks(void) void __init s5pv210_register_clocks(void)
{ {
int ptr; int ptr;
...@@ -1274,11 +1297,15 @@ void __init s5pv210_register_clocks(void) ...@@ -1274,11 +1297,15 @@ void __init s5pv210_register_clocks(void)
for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++) for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
s3c_register_clksrc(sclk_tv[ptr], 1); s3c_register_clksrc(sclk_tv[ptr], 1);
for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
s3c_register_clksrc(clksrc_cdev[ptr], 1);
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
clkdev_add_table(s5pv210_clk_lookup, ARRAY_SIZE(s5pv210_clk_lookup));
s3c24xx_register_clock(&dummy_apb_pclk); s3c24xx_register_clock(&dummy_apb_pclk);
s3c_pwmclk_init(); s3c_pwmclk_init();
......
...@@ -254,28 +254,9 @@ int __init s5pv210_init(void) ...@@ -254,28 +254,9 @@ int __init s5pv210_init(void)
return device_register(&s5pv210_dev); return device_register(&s5pv210_dev);
} }
static struct s3c24xx_uart_clksrc s5pv210_serial_clocks[] = {
[0] = {
.name = "pclk",
.divisor = 1,
.min_baud = 0,
.max_baud = 0,
},
};
/* uart registration process */ /* uart registration process */
void __init s5pv210_init_uarts(struct s3c2410_uartcfg *cfg, int no) void __init s5pv210_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{ {
struct s3c2410_uartcfg *tcfg = cfg;
u32 ucnt;
for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
if (!tcfg->clocks) {
tcfg->clocks = s5pv210_serial_clocks;
tcfg->clocks_size = ARRAY_SIZE(s5pv210_serial_clocks);
}
}
s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no); s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
} }
...@@ -35,90 +35,40 @@ ...@@ -35,90 +35,40 @@
static u64 dma_dmamask = DMA_BIT_MASK(32); static u64 dma_dmamask = DMA_BIT_MASK(32);
struct dma_pl330_peri pdma0_peri[28] = { u8 pdma0_peri[] = {
{ DMACH_UART0_RX,
.peri_id = (u8)DMACH_UART0_RX, DMACH_UART0_TX,
.rqtype = DEVTOMEM, DMACH_UART1_RX,
}, { DMACH_UART1_TX,
.peri_id = (u8)DMACH_UART0_TX, DMACH_UART2_RX,
.rqtype = MEMTODEV, DMACH_UART2_TX,
}, { DMACH_UART3_RX,
.peri_id = (u8)DMACH_UART1_RX, DMACH_UART3_TX,
.rqtype = DEVTOMEM, DMACH_MAX,
}, { DMACH_I2S0_RX,
.peri_id = (u8)DMACH_UART1_TX, DMACH_I2S0_TX,
.rqtype = MEMTODEV, DMACH_I2S0S_TX,
}, { DMACH_I2S1_RX,
.peri_id = (u8)DMACH_UART2_RX, DMACH_I2S1_TX,
.rqtype = DEVTOMEM, DMACH_MAX,
}, { DMACH_MAX,
.peri_id = (u8)DMACH_UART2_TX, DMACH_SPI0_RX,
.rqtype = MEMTODEV, DMACH_SPI0_TX,
}, { DMACH_SPI1_RX,
.peri_id = (u8)DMACH_UART3_RX, DMACH_SPI1_TX,
.rqtype = DEVTOMEM, DMACH_MAX,
}, { DMACH_MAX,
.peri_id = (u8)DMACH_UART3_TX, DMACH_AC97_MICIN,
.rqtype = MEMTODEV, DMACH_AC97_PCMIN,
}, { DMACH_AC97_PCMOUT,
.peri_id = DMACH_MAX, DMACH_MAX,
}, { DMACH_PWM,
.peri_id = (u8)DMACH_I2S0_RX, DMACH_SPDIF,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_I2S0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S0S_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_I2S1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_MAX,
}, {
.peri_id = (u8)DMACH_MAX,
}, {
.peri_id = (u8)DMACH_SPI0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SPI0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SPI1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SPI1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_MAX,
}, {
.peri_id = (u8)DMACH_MAX,
}, {
.peri_id = (u8)DMACH_AC97_MICIN,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_AC97_PCMIN,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_AC97_PCMOUT,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_MAX,
}, {
.peri_id = (u8)DMACH_PWM,
}, {
.peri_id = (u8)DMACH_SPDIF,
.rqtype = MEMTODEV,
},
}; };
struct dma_pl330_platdata s5pv210_pdma0_pdata = { struct dma_pl330_platdata s5pv210_pdma0_pdata = {
.nr_valid_peri = ARRAY_SIZE(pdma0_peri), .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
.peri = pdma0_peri, .peri_id = pdma0_peri,
}; };
struct amba_device s5pv210_device_pdma0 = { struct amba_device s5pv210_device_pdma0 = {
...@@ -137,102 +87,44 @@ struct amba_device s5pv210_device_pdma0 = { ...@@ -137,102 +87,44 @@ struct amba_device s5pv210_device_pdma0 = {
.periphid = 0x00041330, .periphid = 0x00041330,
}; };
struct dma_pl330_peri pdma1_peri[32] = { u8 pdma1_peri[] = {
{ DMACH_UART0_RX,
.peri_id = (u8)DMACH_UART0_RX, DMACH_UART0_TX,
.rqtype = DEVTOMEM, DMACH_UART1_RX,
}, { DMACH_UART1_TX,
.peri_id = (u8)DMACH_UART0_TX, DMACH_UART2_RX,
.rqtype = MEMTODEV, DMACH_UART2_TX,
}, { DMACH_UART3_RX,
.peri_id = (u8)DMACH_UART1_RX, DMACH_UART3_TX,
.rqtype = DEVTOMEM, DMACH_MAX,
}, { DMACH_I2S0_RX,
.peri_id = (u8)DMACH_UART1_TX, DMACH_I2S0_TX,
.rqtype = MEMTODEV, DMACH_I2S0S_TX,
}, { DMACH_I2S1_RX,
.peri_id = (u8)DMACH_UART2_RX, DMACH_I2S1_TX,
.rqtype = DEVTOMEM, DMACH_I2S2_RX,
}, { DMACH_I2S2_TX,
.peri_id = (u8)DMACH_UART2_TX, DMACH_SPI0_RX,
.rqtype = MEMTODEV, DMACH_SPI0_TX,
}, { DMACH_SPI1_RX,
.peri_id = (u8)DMACH_UART3_RX, DMACH_SPI1_TX,
.rqtype = DEVTOMEM, DMACH_MAX,
}, { DMACH_MAX,
.peri_id = (u8)DMACH_UART3_TX, DMACH_PCM0_RX,
.rqtype = MEMTODEV, DMACH_PCM0_TX,
}, { DMACH_PCM1_RX,
.peri_id = DMACH_MAX, DMACH_PCM1_TX,
}, { DMACH_MSM_REQ0,
.peri_id = (u8)DMACH_I2S0_RX, DMACH_MSM_REQ1,
.rqtype = DEVTOMEM, DMACH_MSM_REQ2,
}, { DMACH_MSM_REQ3,
.peri_id = (u8)DMACH_I2S0_TX, DMACH_PCM2_RX,
.rqtype = MEMTODEV, DMACH_PCM2_TX,
}, {
.peri_id = (u8)DMACH_I2S0S_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_I2S1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_I2S2_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_I2S2_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SPI0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SPI0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_SPI1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_SPI1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_MAX,
}, {
.peri_id = (u8)DMACH_MAX,
}, {
.peri_id = (u8)DMACH_PCM0_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_PCM0_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_PCM1_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_PCM1_TX,
.rqtype = MEMTODEV,
}, {
.peri_id = (u8)DMACH_MSM_REQ0,
}, {
.peri_id = (u8)DMACH_MSM_REQ1,
}, {
.peri_id = (u8)DMACH_MSM_REQ2,
}, {
.peri_id = (u8)DMACH_MSM_REQ3,
}, {
.peri_id = (u8)DMACH_PCM2_RX,
.rqtype = DEVTOMEM,
}, {
.peri_id = (u8)DMACH_PCM2_TX,
.rqtype = MEMTODEV,
},
}; };
struct dma_pl330_platdata s5pv210_pdma1_pdata = { struct dma_pl330_platdata s5pv210_pdma1_pdata = {
.nr_valid_peri = ARRAY_SIZE(pdma1_peri), .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
.peri = pdma1_peri, .peri_id = pdma1_peri,
}; };
struct amba_device s5pv210_device_pdma1 = { struct amba_device s5pv210_device_pdma1 = {
...@@ -253,7 +145,12 @@ struct amba_device s5pv210_device_pdma1 = { ...@@ -253,7 +145,12 @@ struct amba_device s5pv210_device_pdma1 = {
static int __init s5pv210_dma_init(void) static int __init s5pv210_dma_init(void)
{ {
dma_cap_set(DMA_SLAVE, s5pv210_pdma0_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, s5pv210_pdma0_pdata.cap_mask);
amba_device_register(&s5pv210_device_pdma0, &iomem_resource); amba_device_register(&s5pv210_device_pdma0, &iomem_resource);
dma_cap_set(DMA_SLAVE, s5pv210_pdma1_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, s5pv210_pdma1_pdata.cap_mask);
amba_device_register(&s5pv210_device_pdma1, &iomem_resource); amba_device_register(&s5pv210_device_pdma1, &iomem_resource);
return 0; return 0;
......
...@@ -118,6 +118,8 @@ ...@@ -118,6 +118,8 @@
#define IRQ_MDNIE3 S5P_IRQ_VIC3(8) #define IRQ_MDNIE3 S5P_IRQ_VIC3(8)
#define IRQ_VIC_END S5P_IRQ_VIC3(31) #define IRQ_VIC_END S5P_IRQ_VIC3(31)
#define IRQ_TIMER_BASE (11)
#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
#define S5P_EINT_BASE2 (IRQ_VIC_END + 1) #define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
......
...@@ -32,6 +32,8 @@ obj-$(CONFIG_MACH_SEABOARD) += board-seaboard-pinmux.o ...@@ -32,6 +32,8 @@ obj-$(CONFIG_MACH_SEABOARD) += board-seaboard-pinmux.o
obj-$(CONFIG_MACH_TEGRA_DT) += board-dt.o obj-$(CONFIG_MACH_TEGRA_DT) += board-dt.o
obj-$(CONFIG_MACH_TEGRA_DT) += board-harmony-pinmux.o obj-$(CONFIG_MACH_TEGRA_DT) += board-harmony-pinmux.o
obj-$(CONFIG_MACH_TEGRA_DT) += board-seaboard-pinmux.o obj-$(CONFIG_MACH_TEGRA_DT) += board-seaboard-pinmux.o
obj-$(CONFIG_MACH_TEGRA_DT) += board-paz00-pinmux.o
obj-$(CONFIG_MACH_TEGRA_DT) += board-trimslice-pinmux.o
obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice.o obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice.o
obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice-pinmux.o obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice-pinmux.o
...@@ -3,5 +3,7 @@ params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100 ...@@ -3,5 +3,7 @@ params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100
initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000 initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000
dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb
dtb-$(CONFIG_MACH_PAZ00) += tegra-paz00.dtb
dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb
dtb-$(CONFIG_MACH_TRIMSLICE) += tegra-trimslice.dtb
dtb-$(CONFIG_MACH_VENTANA) += tegra-ventana.dtb dtb-$(CONFIG_MACH_VENTANA) += tegra-ventana.dtb
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/hardware/gic.h>
#include <mach/iomap.h> #include <mach/iomap.h>
#include <mach/irqs.h> #include <mach/irqs.h>
...@@ -47,9 +48,22 @@ ...@@ -47,9 +48,22 @@
#include "devices.h" #include "devices.h"
void harmony_pinmux_init(void); void harmony_pinmux_init(void);
void paz00_pinmux_init(void);
void seaboard_pinmux_init(void); void seaboard_pinmux_init(void);
void trimslice_pinmux_init(void);
void ventana_pinmux_init(void); void ventana_pinmux_init(void);
static const struct of_device_id tegra_dt_irq_match[] __initconst = {
{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init },
{ }
};
void __init tegra_dt_init_irq(void)
{
tegra_init_irq();
of_irq_init(tegra_dt_irq_match);
}
struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL), OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL),
...@@ -58,16 +72,30 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { ...@@ -58,16 +72,30 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C_BASE, "tegra-i2c.0", NULL), OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C_BASE, "tegra-i2c.0", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C2_BASE, "tegra-i2c.1", NULL), OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C2_BASE, "tegra-i2c.1", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C3_BASE, "tegra-i2c.2", NULL), OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C3_BASE, "tegra-i2c.2", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_DVC_BASE, "tegra-i2c.3", NULL), OF_DEV_AUXDATA("nvidia,tegra20-i2c-dvc", TEGRA_DVC_BASE, "tegra-i2c.3", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.0", NULL), OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.0", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.1", NULL), OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S2_BASE, "tegra-i2s.1", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-das", TEGRA_APB_MISC_DAS_BASE, "tegra-das", NULL), OF_DEV_AUXDATA("nvidia,tegra20-das", TEGRA_APB_MISC_DAS_BASE, "tegra-das", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB_BASE, "tegra-ehci.0",
&tegra_ehci1_device.dev.platform_data),
OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB2_BASE, "tegra-ehci.1",
&tegra_ehci2_device.dev.platform_data),
OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2",
&tegra_ehci3_device.dev.platform_data),
{} {}
}; };
static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = { static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
/* name parent rate enabled */ /* name parent rate enabled */
{ "uartd", "pll_p", 216000000, true }, { "uartd", "pll_p", 216000000, true },
{ "usbd", "clk_m", 12000000, false },
{ "usb2", "clk_m", 12000000, false },
{ "usb3", "clk_m", 12000000, false },
{ "pll_a", "pll_p_out1", 56448000, true },
{ "pll_a_out0", "pll_a", 11289600, true },
{ "cdev1", NULL, 0, true },
{ "i2s1", "pll_a_out0", 11289600, false},
{ "i2s2", "pll_a_out0", 11289600, false},
{ NULL, NULL, 0, 0}, { NULL, NULL, 0, 0},
}; };
...@@ -76,30 +104,21 @@ static struct of_device_id tegra_dt_match_table[] __initdata = { ...@@ -76,30 +104,21 @@ static struct of_device_id tegra_dt_match_table[] __initdata = {
{} {}
}; };
static struct of_device_id tegra_dt_gic_match[] __initdata = {
{ .compatible = "nvidia,tegra20-gic", },
{}
};
static struct { static struct {
char *machine; char *machine;
void (*init)(void); void (*init)(void);
} pinmux_configs[] = { } pinmux_configs[] = {
{ "compulab,trimslice", trimslice_pinmux_init },
{ "nvidia,harmony", harmony_pinmux_init }, { "nvidia,harmony", harmony_pinmux_init },
{ "compal,paz00", paz00_pinmux_init },
{ "nvidia,seaboard", seaboard_pinmux_init }, { "nvidia,seaboard", seaboard_pinmux_init },
{ "nvidia,ventana", ventana_pinmux_init }, { "nvidia,ventana", ventana_pinmux_init },
}; };
static void __init tegra_dt_init(void) static void __init tegra_dt_init(void)
{ {
struct device_node *node;
int i; int i;
node = of_find_matching_node_by_address(NULL, tegra_dt_gic_match,
TEGRA_ARM_INT_DIST_BASE);
if (node)
irq_domain_add_simple(node, INT_GIC_BASE);
tegra_clk_init_from_table(tegra_dt_clk_init_table); tegra_clk_init_from_table(tegra_dt_clk_init_table);
/* /*
...@@ -121,7 +140,9 @@ static void __init tegra_dt_init(void) ...@@ -121,7 +140,9 @@ static void __init tegra_dt_init(void)
} }
static const char * tegra_dt_board_compat[] = { static const char * tegra_dt_board_compat[] = {
"compulab,trimslice",
"nvidia,harmony", "nvidia,harmony",
"compal,paz00",
"nvidia,seaboard", "nvidia,seaboard",
"nvidia,ventana", "nvidia,ventana",
NULL NULL
...@@ -130,7 +151,7 @@ static const char * tegra_dt_board_compat[] = { ...@@ -130,7 +151,7 @@ static const char * tegra_dt_board_compat[] = {
DT_MACHINE_START(TEGRA_DT, "nVidia Tegra (Flattened Device Tree)") DT_MACHINE_START(TEGRA_DT, "nVidia Tegra (Flattened Device Tree)")
.map_io = tegra_map_common_io, .map_io = tegra_map_common_io,
.init_early = tegra_init_early, .init_early = tegra_init_early,
.init_irq = tegra_init_irq, .init_irq = tegra_dt_init_irq,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
.timer = &tegra_timer, .timer = &tegra_timer,
.init_machine = tegra_dt_init, .init_machine = tegra_dt_init,
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h>
#include <asm/hardware/gic.h> #include <asm/hardware/gic.h>
...@@ -125,6 +126,11 @@ void __init tegra_init_irq(void) ...@@ -125,6 +126,11 @@ void __init tegra_init_irq(void)
gic_arch_extn.irq_unmask = tegra_unmask; gic_arch_extn.irq_unmask = tegra_unmask;
gic_arch_extn.irq_retrigger = tegra_retrigger; gic_arch_extn.irq_retrigger = tegra_retrigger;
gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), /*
IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); * Check if there is a devicetree present, since the GIC will be
* initialized elsewhere under DT.
*/
if (!of_have_populated_dt())
gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
} }
...@@ -297,13 +297,6 @@ static struct clksrc_clk clk_usb_bus_host = { ...@@ -297,13 +297,6 @@ static struct clksrc_clk clk_usb_bus_host = {
static struct clksrc_clk clksrc_clks[] = { static struct clksrc_clk clksrc_clks[] = {
{ {
/* ART baud-rate clock sourced from esysclk via a divisor */
.clk = {
.name = "uartclk",
.parent = &clk_esysclk.clk,
},
.reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
}, {
/* camera interface bus-clock, divided down from esysclk */ /* camera interface bus-clock, divided down from esysclk */
.clk = { .clk = {
.name = "camif-upll", /* same as 2440 name */ .name = "camif-upll", /* same as 2440 name */
...@@ -323,6 +316,15 @@ static struct clksrc_clk clksrc_clks[] = { ...@@ -323,6 +316,15 @@ static struct clksrc_clk clksrc_clks[] = {
}, },
}; };
static struct clksrc_clk clk_esys_uart = {
/* ART baud-rate clock sourced from esysclk via a divisor */
.clk = {
.name = "uartclk",
.parent = &clk_esysclk.clk,
},
.reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
};
static struct clk clk_i2s_ext = { static struct clk clk_i2s_ext = {
.name = "i2s-ext", .name = "i2s-ext",
}; };
...@@ -589,6 +591,12 @@ static struct clksrc_clk *clksrcs[] __initdata = { ...@@ -589,6 +591,12 @@ static struct clksrc_clk *clksrcs[] __initdata = {
&clk_arm, &clk_arm,
}; };
static struct clk_lookup s3c2443_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk),
};
void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
unsigned int *divs, int nr_divs, unsigned int *divs, int nr_divs,
int divmask) int divmask)
...@@ -618,6 +626,7 @@ void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, ...@@ -618,6 +626,7 @@ void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
/* See s3c2443/etc notes on disabling clocks at init time */ /* See s3c2443/etc notes on disabling clocks at init time */
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
s3c2443_common_setup_clocks(get_mpll); s3c2443_common_setup_clocks(get_mpll);
} }
...@@ -18,23 +18,24 @@ ...@@ -18,23 +18,24 @@
#include <mach/dma.h> #include <mach/dma.h>
static inline bool pl330_filter(struct dma_chan *chan, void *param)
{
struct dma_pl330_peri *peri = chan->private;
return peri->peri_id == (unsigned)param;
}
static unsigned samsung_dmadev_request(enum dma_ch dma_ch, static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
struct samsung_dma_info *info) struct samsung_dma_info *info)
{ {
struct dma_chan *chan; struct dma_chan *chan;
dma_cap_mask_t mask; dma_cap_mask_t mask;
struct dma_slave_config slave_config; struct dma_slave_config slave_config;
void *filter_param;
dma_cap_zero(mask); dma_cap_zero(mask);
dma_cap_set(info->cap, mask); dma_cap_set(info->cap, mask);
chan = dma_request_channel(mask, pl330_filter, (void *)dma_ch); /*
* If a dma channel property of a device node from device tree is
* specified, use that as the fliter parameter.
*/
filter_param = (dma_ch == DMACH_DT_PROP) ? (void *)info->dt_dmach_prop :
(void *)dma_ch;
chan = dma_request_channel(mask, pl330_filter, filter_param);
if (info->direction == DMA_FROM_DEVICE) { if (info->direction == DMA_FROM_DEVICE) {
memset(&slave_config, 0, sizeof(struct dma_slave_config)); memset(&slave_config, 0, sizeof(struct dma_slave_config));
......
...@@ -31,6 +31,7 @@ struct samsung_dma_info { ...@@ -31,6 +31,7 @@ struct samsung_dma_info {
enum dma_slave_buswidth width; enum dma_slave_buswidth width;
dma_addr_t fifo; dma_addr_t fifo;
struct s3c2410_dma_client *client; struct s3c2410_dma_client *client;
struct property *dt_dmach_prop;
}; };
struct samsung_dma_ops { struct samsung_dma_ops {
......
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
* use these just as IDs. * use these just as IDs.
*/ */
enum dma_ch { enum dma_ch {
DMACH_UART0_RX, DMACH_DT_PROP = -1,
DMACH_UART0_RX = 0,
DMACH_UART0_TX, DMACH_UART0_TX,
DMACH_UART1_RX, DMACH_UART1_RX,
DMACH_UART1_TX, DMACH_UART1_TX,
......
...@@ -44,13 +44,14 @@ ...@@ -44,13 +44,14 @@
#define S5P_IRQ_VIC2(x) (S5P_VIC2_BASE + (x)) #define S5P_IRQ_VIC2(x) (S5P_VIC2_BASE + (x))
#define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x)) #define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x))
#define S5P_TIMER_IRQ(x) (11 + (x)) #define S5P_TIMER_IRQ(x) (IRQ_TIMER_BASE + (x))
#define IRQ_TIMER0 S5P_TIMER_IRQ(0) #define IRQ_TIMER0 S5P_TIMER_IRQ(0)
#define IRQ_TIMER1 S5P_TIMER_IRQ(1) #define IRQ_TIMER1 S5P_TIMER_IRQ(1)
#define IRQ_TIMER2 S5P_TIMER_IRQ(2) #define IRQ_TIMER2 S5P_TIMER_IRQ(2)
#define IRQ_TIMER3 S5P_TIMER_IRQ(3) #define IRQ_TIMER3 S5P_TIMER_IRQ(3)
#define IRQ_TIMER4 S5P_TIMER_IRQ(4) #define IRQ_TIMER4 S5P_TIMER_IRQ(4)
#define IRQ_TIMER_COUNT (5)
#define IRQ_EINT(x) ((x) < 16 ? ((x) + S5P_EINT_BASE1) \ #define IRQ_EINT(x) ((x) < 16 ? ((x) + S5P_EINT_BASE1) \
: ((x) - 16 + S5P_EINT_BASE2)) : ((x) - 16 + S5P_EINT_BASE2))
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
#define S3C2410_LCON_IRM (1<<6) #define S3C2410_LCON_IRM (1<<6)
#define S3C2440_UCON_CLKMASK (3<<10) #define S3C2440_UCON_CLKMASK (3<<10)
#define S3C2440_UCON_CLKSHIFT (10)
#define S3C2440_UCON_PCLK (0<<10) #define S3C2440_UCON_PCLK (0<<10)
#define S3C2440_UCON_UCLK (1<<10) #define S3C2440_UCON_UCLK (1<<10)
#define S3C2440_UCON_PCLK2 (2<<10) #define S3C2440_UCON_PCLK2 (2<<10)
...@@ -78,6 +79,7 @@ ...@@ -78,6 +79,7 @@
#define S3C2443_UCON_EPLL (3<<10) #define S3C2443_UCON_EPLL (3<<10)
#define S3C6400_UCON_CLKMASK (3<<10) #define S3C6400_UCON_CLKMASK (3<<10)
#define S3C6400_UCON_CLKSHIFT (10)
#define S3C6400_UCON_PCLK (0<<10) #define S3C6400_UCON_PCLK (0<<10)
#define S3C6400_UCON_PCLK2 (2<<10) #define S3C6400_UCON_PCLK2 (2<<10)
#define S3C6400_UCON_UCLK0 (1<<10) #define S3C6400_UCON_UCLK0 (1<<10)
...@@ -90,11 +92,14 @@ ...@@ -90,11 +92,14 @@
#define S3C2440_UCON_DIVSHIFT (12) #define S3C2440_UCON_DIVSHIFT (12)
#define S3C2412_UCON_CLKMASK (3<<10) #define S3C2412_UCON_CLKMASK (3<<10)
#define S3C2412_UCON_CLKSHIFT (10)
#define S3C2412_UCON_UCLK (1<<10) #define S3C2412_UCON_UCLK (1<<10)
#define S3C2412_UCON_USYSCLK (3<<10) #define S3C2412_UCON_USYSCLK (3<<10)
#define S3C2412_UCON_PCLK (0<<10) #define S3C2412_UCON_PCLK (0<<10)
#define S3C2412_UCON_PCLK2 (2<<10) #define S3C2412_UCON_PCLK2 (2<<10)
#define S3C2410_UCON_CLKMASK (1 << 10)
#define S3C2410_UCON_CLKSHIFT (10)
#define S3C2410_UCON_UCLK (1<<10) #define S3C2410_UCON_UCLK (1<<10)
#define S3C2410_UCON_SBREAK (1<<4) #define S3C2410_UCON_SBREAK (1<<4)
...@@ -193,6 +198,7 @@ ...@@ -193,6 +198,7 @@
/* Following are specific to S5PV210 */ /* Following are specific to S5PV210 */
#define S5PV210_UCON_CLKMASK (1<<10) #define S5PV210_UCON_CLKMASK (1<<10)
#define S5PV210_UCON_CLKSHIFT (10)
#define S5PV210_UCON_PCLK (0<<10) #define S5PV210_UCON_PCLK (0<<10)
#define S5PV210_UCON_UCLK (1<<10) #define S5PV210_UCON_UCLK (1<<10)
...@@ -221,29 +227,24 @@ ...@@ -221,29 +227,24 @@
#define S5PV210_UFSTAT_RXMASK (255<<0) #define S5PV210_UFSTAT_RXMASK (255<<0)
#define S5PV210_UFSTAT_RXSHIFT (0) #define S5PV210_UFSTAT_RXSHIFT (0)
#define NO_NEED_CHECK_CLKSRC 1 #define S3C2410_UCON_CLKSEL0 (1 << 0)
#define S3C2410_UCON_CLKSEL1 (1 << 1)
#define S3C2410_UCON_CLKSEL2 (1 << 2)
#define S3C2410_UCON_CLKSEL3 (1 << 3)
#ifndef __ASSEMBLY__ /* Default values for s5pv210 UCON and UFCON uart registers */
#define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
S3C2410_UCON_TXIRQMODE | \
S3C2410_UCON_RXIRQMODE | \
S3C2410_UCON_RXFIFO_TOI | \
S3C2443_UCON_RXERR_IRQEN)
/* struct s3c24xx_uart_clksrc #define S5PV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
* S5PV210_UFCON_TXTRIG4 | \
* this structure defines a named clock source that can be used for the S5PV210_UFCON_RXTRIG4)
* uart, so that the best clock can be selected for the requested baud
* rate.
*
* min_baud and max_baud define the range of baud-rates this clock is
* acceptable for, if they are both zero, it is assumed any baud rate that
* can be generated from this clock will be used.
*
* divisor gives the divisor from the clock to the one seen by the uart
*/
struct s3c24xx_uart_clksrc { #ifndef __ASSEMBLY__
const char *name;
unsigned int divisor;
unsigned int min_baud;
unsigned int max_baud;
};
/* configuration structure for per-machine configurations for the /* configuration structure for per-machine configurations for the
* serial port * serial port
...@@ -257,15 +258,13 @@ struct s3c2410_uartcfg { ...@@ -257,15 +258,13 @@ struct s3c2410_uartcfg {
unsigned char unused; unsigned char unused;
unsigned short flags; unsigned short flags;
upf_t uart_flags; /* default uart flags */ upf_t uart_flags; /* default uart flags */
unsigned int clk_sel;
unsigned int has_fracval; unsigned int has_fracval;
unsigned long ucon; /* value of ucon for port */ unsigned long ucon; /* value of ucon for port */
unsigned long ulcon; /* value of ulcon for port */ unsigned long ulcon; /* value of ulcon for port */
unsigned long ufcon; /* value of ufcon for port */ unsigned long ufcon; /* value of ufcon for port */
struct s3c24xx_uart_clksrc *clocks;
unsigned int clocks_size;
}; };
/* s3c24xx_uart_devs /* s3c24xx_uart_devs
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/amba/pl330.h> #include <linux/amba/pl330.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/of.h>
#define NR_DEFAULT_DESC 16 #define NR_DEFAULT_DESC 16
...@@ -116,6 +117,9 @@ struct dma_pl330_desc { ...@@ -116,6 +117,9 @@ struct dma_pl330_desc {
struct dma_pl330_chan *pchan; struct dma_pl330_chan *pchan;
}; };
/* forward declaration */
static struct amba_driver pl330_driver;
static inline struct dma_pl330_chan * static inline struct dma_pl330_chan *
to_pchan(struct dma_chan *ch) to_pchan(struct dma_chan *ch)
{ {
...@@ -267,6 +271,32 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err) ...@@ -267,6 +271,32 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
tasklet_schedule(&pch->task); tasklet_schedule(&pch->task);
} }
bool pl330_filter(struct dma_chan *chan, void *param)
{
u8 *peri_id;
if (chan->device->dev->driver != &pl330_driver.drv)
return false;
#ifdef CONFIG_OF
if (chan->device->dev->of_node) {
const __be32 *prop_value;
phandle phandle;
struct device_node *node;
prop_value = ((struct property *)param)->value;
phandle = be32_to_cpup(prop_value++);
node = of_find_node_by_phandle(phandle);
return ((chan->private == node) &&
(chan->chan_id == be32_to_cpup(prop_value)));
}
#endif
peri_id = chan->private;
return *peri_id == (unsigned)param;
}
EXPORT_SYMBOL(pl330_filter);
static int pl330_alloc_chan_resources(struct dma_chan *chan) static int pl330_alloc_chan_resources(struct dma_chan *chan)
{ {
struct dma_pl330_chan *pch = to_pchan(chan); struct dma_pl330_chan *pch = to_pchan(chan);
...@@ -497,7 +527,7 @@ pluck_desc(struct dma_pl330_dmac *pdmac) ...@@ -497,7 +527,7 @@ pluck_desc(struct dma_pl330_dmac *pdmac)
static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
{ {
struct dma_pl330_dmac *pdmac = pch->dmac; struct dma_pl330_dmac *pdmac = pch->dmac;
struct dma_pl330_peri *peri = pch->chan.private; u8 *peri_id = pch->chan.private;
struct dma_pl330_desc *desc; struct dma_pl330_desc *desc;
/* Pluck one desc from the pool of DMAC */ /* Pluck one desc from the pool of DMAC */
...@@ -522,13 +552,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) ...@@ -522,13 +552,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
desc->txd.cookie = 0; desc->txd.cookie = 0;
async_tx_ack(&desc->txd); async_tx_ack(&desc->txd);
if (peri) { desc->req.peri = peri_id ? pch->chan.chan_id : 0;
desc->req.rqtype = peri->rqtype;
desc->req.peri = pch->chan.chan_id;
} else {
desc->req.rqtype = MEMTOMEM;
desc->req.peri = 0;
}
dma_async_tx_descriptor_init(&desc->txd, &pch->chan); dma_async_tx_descriptor_init(&desc->txd, &pch->chan);
...@@ -615,12 +639,14 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( ...@@ -615,12 +639,14 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
case DMA_TO_DEVICE: case DMA_TO_DEVICE:
desc->rqcfg.src_inc = 1; desc->rqcfg.src_inc = 1;
desc->rqcfg.dst_inc = 0; desc->rqcfg.dst_inc = 0;
desc->req.rqtype = MEMTODEV;
src = dma_addr; src = dma_addr;
dst = pch->fifo_addr; dst = pch->fifo_addr;
break; break;
case DMA_FROM_DEVICE: case DMA_FROM_DEVICE:
desc->rqcfg.src_inc = 0; desc->rqcfg.src_inc = 0;
desc->rqcfg.dst_inc = 1; desc->rqcfg.dst_inc = 1;
desc->req.rqtype = DEVTOMEM;
src = pch->fifo_addr; src = pch->fifo_addr;
dst = dma_addr; dst = dma_addr;
break; break;
...@@ -646,16 +672,12 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, ...@@ -646,16 +672,12 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
{ {
struct dma_pl330_desc *desc; struct dma_pl330_desc *desc;
struct dma_pl330_chan *pch = to_pchan(chan); struct dma_pl330_chan *pch = to_pchan(chan);
struct dma_pl330_peri *peri = chan->private;
struct pl330_info *pi; struct pl330_info *pi;
int burst; int burst;
if (unlikely(!pch || !len)) if (unlikely(!pch || !len))
return NULL; return NULL;
if (peri && peri->rqtype != MEMTOMEM)
return NULL;
pi = &pch->dmac->pif; pi = &pch->dmac->pif;
desc = __pl330_prep_dma_memcpy(pch, dst, src, len); desc = __pl330_prep_dma_memcpy(pch, dst, src, len);
...@@ -664,6 +686,7 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, ...@@ -664,6 +686,7 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
desc->rqcfg.src_inc = 1; desc->rqcfg.src_inc = 1;
desc->rqcfg.dst_inc = 1; desc->rqcfg.dst_inc = 1;
desc->req.rqtype = MEMTOMEM;
/* Select max possible burst size */ /* Select max possible burst size */
burst = pi->pcfg.data_bus_width / 8; burst = pi->pcfg.data_bus_width / 8;
...@@ -692,25 +715,14 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, ...@@ -692,25 +715,14 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
{ {
struct dma_pl330_desc *first, *desc = NULL; struct dma_pl330_desc *first, *desc = NULL;
struct dma_pl330_chan *pch = to_pchan(chan); struct dma_pl330_chan *pch = to_pchan(chan);
struct dma_pl330_peri *peri = chan->private;
struct scatterlist *sg; struct scatterlist *sg;
unsigned long flags; unsigned long flags;
int i; int i;
dma_addr_t addr; dma_addr_t addr;
if (unlikely(!pch || !sgl || !sg_len || !peri)) if (unlikely(!pch || !sgl || !sg_len))
return NULL; return NULL;
/* Make sure the direction is consistent */
if ((direction == DMA_TO_DEVICE &&
peri->rqtype != MEMTODEV) ||
(direction == DMA_FROM_DEVICE &&
peri->rqtype != DEVTOMEM)) {
dev_err(pch->dmac->pif.dev, "%s:%d Invalid Direction\n",
__func__, __LINE__);
return NULL;
}
addr = pch->fifo_addr; addr = pch->fifo_addr;
first = NULL; first = NULL;
...@@ -750,11 +762,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, ...@@ -750,11 +762,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
if (direction == DMA_TO_DEVICE) { if (direction == DMA_TO_DEVICE) {
desc->rqcfg.src_inc = 1; desc->rqcfg.src_inc = 1;
desc->rqcfg.dst_inc = 0; desc->rqcfg.dst_inc = 0;
desc->req.rqtype = MEMTODEV;
fill_px(&desc->px, fill_px(&desc->px,
addr, sg_dma_address(sg), sg_dma_len(sg)); addr, sg_dma_address(sg), sg_dma_len(sg));
} else { } else {
desc->rqcfg.src_inc = 0; desc->rqcfg.src_inc = 0;
desc->rqcfg.dst_inc = 1; desc->rqcfg.dst_inc = 1;
desc->req.rqtype = DEVTOMEM;
fill_px(&desc->px, fill_px(&desc->px,
sg_dma_address(sg), addr, sg_dma_len(sg)); sg_dma_address(sg), addr, sg_dma_len(sg));
} }
...@@ -856,32 +870,16 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -856,32 +870,16 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
INIT_LIST_HEAD(&pd->channels); INIT_LIST_HEAD(&pd->channels);
/* Initialize channel parameters */ /* Initialize channel parameters */
num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan); num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri,
(u8)pi->pcfg.num_chan);
pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
for (i = 0; i < num_chan; i++) { for (i = 0; i < num_chan; i++) {
pch = &pdmac->peripherals[i]; pch = &pdmac->peripherals[i];
if (pdat) { if (!adev->dev.of_node)
struct dma_pl330_peri *peri = &pdat->peri[i]; pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
else
switch (peri->rqtype) { pch->chan.private = adev->dev.of_node;
case MEMTOMEM:
dma_cap_set(DMA_MEMCPY, pd->cap_mask);
break;
case MEMTODEV:
case DEVTOMEM:
dma_cap_set(DMA_SLAVE, pd->cap_mask);
dma_cap_set(DMA_CYCLIC, pd->cap_mask);
break;
default:
dev_err(&adev->dev, "DEVTODEV Not Supported\n");
continue;
}
pch->chan.private = peri;
} else {
dma_cap_set(DMA_MEMCPY, pd->cap_mask);
pch->chan.private = NULL;
}
INIT_LIST_HEAD(&pch->work_list); INIT_LIST_HEAD(&pch->work_list);
spin_lock_init(&pch->lock); spin_lock_init(&pch->lock);
...@@ -894,6 +892,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -894,6 +892,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
} }
pd->dev = &adev->dev; pd->dev = &adev->dev;
if (pdat) {
pd->cap_mask = pdat->cap_mask;
} else {
dma_cap_set(DMA_MEMCPY, pd->cap_mask);
if (pi->pcfg.num_peri) {
dma_cap_set(DMA_SLAVE, pd->cap_mask);
dma_cap_set(DMA_CYCLIC, pd->cap_mask);
}
}
pd->device_alloc_chan_resources = pl330_alloc_chan_resources; pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
pd->device_free_chan_resources = pl330_free_chan_resources; pd->device_free_chan_resources = pl330_free_chan_resources;
......
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/of_address.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -2383,6 +2386,63 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = { ...@@ -2383,6 +2386,63 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = {
#endif #endif
}; };
#if defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF)
static int exynos4_gpio_xlate(struct gpio_chip *gc, struct device_node *np,
const void *gpio_spec, u32 *flags)
{
const __be32 *gpio = gpio_spec;
const u32 n = be32_to_cpup(gpio);
unsigned int pin = gc->base + be32_to_cpu(gpio[0]);
if (WARN_ON(gc->of_gpio_n_cells < 4))
return -EINVAL;
if (n > gc->ngpio)
return -EINVAL;
if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(be32_to_cpu(gpio[1]))))
pr_warn("gpio_xlate: failed to set pin function\n");
if (s3c_gpio_setpull(pin, be32_to_cpu(gpio[2])))
pr_warn("gpio_xlate: failed to set pin pull up/down\n");
if (s5p_gpio_set_drvstr(pin, be32_to_cpu(gpio[3])))
pr_warn("gpio_xlate: failed to set pin drive strength\n");
return n;
}
static const struct of_device_id exynos4_gpio_dt_match[] __initdata = {
{ .compatible = "samsung,exynos4-gpio", },
{}
};
static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
u64 base, u64 offset)
{
struct gpio_chip *gc = &chip->chip;
u64 address;
if (!of_have_populated_dt())
return;
address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
gc->of_node = of_find_matching_node_by_address(NULL,
exynos4_gpio_dt_match, address);
if (!gc->of_node) {
pr_info("gpio: device tree node not found for gpio controller"
" with base address %08llx\n", address);
return;
}
gc->of_gpio_n_cells = 4;
gc->of_xlate = exynos4_gpio_xlate;
}
#elif defined(CONFIG_ARCH_EXYNOS4)
static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
u64 base, u64 offset)
{
return;
}
#endif /* defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF) */
/* TODO: cleanup soc_is_* */ /* TODO: cleanup soc_is_* */
static __init int samsung_gpiolib_init(void) static __init int samsung_gpiolib_init(void)
{ {
...@@ -2464,6 +2524,10 @@ static __init int samsung_gpiolib_init(void) ...@@ -2464,6 +2524,10 @@ static __init int samsung_gpiolib_init(void)
chip->config = &exynos4_gpio_cfg; chip->config = &exynos4_gpio_cfg;
chip->group = group++; chip->group = group++;
} }
#ifdef CONFIG_CPU_EXYNOS4210
exynos4_gpiolib_attach_ofnode(chip,
EXYNOS4_PA_GPIO1, i * 0x20);
#endif
} }
samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, nr_chips, S5P_VA_GPIO1); samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, nr_chips, S5P_VA_GPIO1);
...@@ -2476,6 +2540,10 @@ static __init int samsung_gpiolib_init(void) ...@@ -2476,6 +2540,10 @@ static __init int samsung_gpiolib_init(void)
chip->config = &exynos4_gpio_cfg; chip->config = &exynos4_gpio_cfg;
chip->group = group++; chip->group = group++;
} }
#ifdef CONFIG_CPU_EXYNOS4210
exynos4_gpiolib_attach_ofnode(chip,
EXYNOS4_PA_GPIO2, i * 0x20);
#endif
} }
samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, nr_chips, S5P_VA_GPIO2); samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, nr_chips, S5P_VA_GPIO2);
...@@ -2488,6 +2556,10 @@ static __init int samsung_gpiolib_init(void) ...@@ -2488,6 +2556,10 @@ static __init int samsung_gpiolib_init(void)
chip->config = &exynos4_gpio_cfg; chip->config = &exynos4_gpio_cfg;
chip->group = group++; chip->group = group++;
} }
#ifdef CONFIG_CPU_EXYNOS4210
exynos4_gpiolib_attach_ofnode(chip,
EXYNOS4_PA_GPIO3, i * 0x20);
#endif
} }
samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, nr_chips, S5P_VA_GPIO3); samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, nr_chips, S5P_VA_GPIO3);
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <plat/keypad.h> #include <plat/keypad.h>
...@@ -68,31 +70,26 @@ struct samsung_keypad { ...@@ -68,31 +70,26 @@ struct samsung_keypad {
wait_queue_head_t wait; wait_queue_head_t wait;
bool stopped; bool stopped;
int irq; int irq;
enum samsung_keypad_type type;
unsigned int row_shift; unsigned int row_shift;
unsigned int rows; unsigned int rows;
unsigned int cols; unsigned int cols;
unsigned int row_state[SAMSUNG_MAX_COLS]; unsigned int row_state[SAMSUNG_MAX_COLS];
#ifdef CONFIG_OF
int row_gpios[SAMSUNG_MAX_ROWS];
int col_gpios[SAMSUNG_MAX_COLS];
#endif
unsigned short keycodes[]; unsigned short keycodes[];
}; };
static int samsung_keypad_is_s5pv210(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
enum samsung_keypad_type type =
platform_get_device_id(pdev)->driver_data;
return type == KEYPAD_TYPE_S5PV210;
}
static void samsung_keypad_scan(struct samsung_keypad *keypad, static void samsung_keypad_scan(struct samsung_keypad *keypad,
unsigned int *row_state) unsigned int *row_state)
{ {
struct device *dev = keypad->input_dev->dev.parent;
unsigned int col; unsigned int col;
unsigned int val; unsigned int val;
for (col = 0; col < keypad->cols; col++) { for (col = 0; col < keypad->cols; col++) {
if (samsung_keypad_is_s5pv210(dev)) { if (keypad->type == KEYPAD_TYPE_S5PV210) {
val = S5PV210_KEYIFCOLEN_MASK; val = S5PV210_KEYIFCOLEN_MASK;
val &= ~(1 << col) << 8; val &= ~(1 << col) << 8;
} else { } else {
...@@ -235,6 +232,126 @@ static void samsung_keypad_close(struct input_dev *input_dev) ...@@ -235,6 +232,126 @@ static void samsung_keypad_close(struct input_dev *input_dev)
samsung_keypad_stop(keypad); samsung_keypad_stop(keypad);
} }
#ifdef CONFIG_OF
static struct samsung_keypad_platdata *samsung_keypad_parse_dt(
struct device *dev)
{
struct samsung_keypad_platdata *pdata;
struct matrix_keymap_data *keymap_data;
uint32_t *keymap, num_rows = 0, num_cols = 0;
struct device_node *np = dev->of_node, *key_np;
unsigned int key_count = 0;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
dev_err(dev, "could not allocate memory for platform data\n");
return NULL;
}
of_property_read_u32(np, "samsung,keypad-num-rows", &num_rows);
of_property_read_u32(np, "samsung,keypad-num-columns", &num_cols);
if (!num_rows || !num_cols) {
dev_err(dev, "number of keypad rows/columns not specified\n");
return NULL;
}
pdata->rows = num_rows;
pdata->cols = num_cols;
keymap_data = devm_kzalloc(dev, sizeof(*keymap_data), GFP_KERNEL);
if (!keymap_data) {
dev_err(dev, "could not allocate memory for keymap data\n");
return NULL;
}
pdata->keymap_data = keymap_data;
for_each_child_of_node(np, key_np)
key_count++;
keymap_data->keymap_size = key_count;
keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL);
if (!keymap) {
dev_err(dev, "could not allocate memory for keymap\n");
return NULL;
}
keymap_data->keymap = keymap;
for_each_child_of_node(np, key_np) {
u32 row, col, key_code;
of_property_read_u32(key_np, "keypad,row", &row);
of_property_read_u32(key_np, "keypad,column", &col);
of_property_read_u32(key_np, "linux,code", &key_code);
*keymap++ = KEY(row, col, key_code);
}
if (of_get_property(np, "linux,input-no-autorepeat", NULL))
pdata->no_autorepeat = true;
if (of_get_property(np, "linux,input-wakeup", NULL))
pdata->wakeup = true;
return pdata;
}
static void samsung_keypad_parse_dt_gpio(struct device *dev,
struct samsung_keypad *keypad)
{
struct device_node *np = dev->of_node;
int gpio, ret, row, col;
for (row = 0; row < keypad->rows; row++) {
gpio = of_get_named_gpio(np, "row-gpios", row);
keypad->row_gpios[row] = gpio;
if (!gpio_is_valid(gpio)) {
dev_err(dev, "keypad row[%d]: invalid gpio %d\n",
row, gpio);
continue;
}
ret = gpio_request(gpio, "keypad-row");
if (ret)
dev_err(dev, "keypad row[%d] gpio request failed\n",
row);
}
for (col = 0; col < keypad->cols; col++) {
gpio = of_get_named_gpio(np, "col-gpios", col);
keypad->col_gpios[col] = gpio;
if (!gpio_is_valid(gpio)) {
dev_err(dev, "keypad column[%d]: invalid gpio %d\n",
col, gpio);
continue;
}
ret = gpio_request(gpio, "keypad-col");
if (ret)
dev_err(dev, "keypad column[%d] gpio request failed\n",
col);
}
}
static void samsung_keypad_dt_gpio_free(struct samsung_keypad *keypad)
{
int cnt;
for (cnt = 0; cnt < keypad->rows; cnt++)
if (gpio_is_valid(keypad->row_gpios[cnt]))
gpio_free(keypad->row_gpios[cnt]);
for (cnt = 0; cnt < keypad->cols; cnt++)
if (gpio_is_valid(keypad->col_gpios[cnt]))
gpio_free(keypad->col_gpios[cnt]);
}
#else
static
struct samsung_keypad_platdata *samsung_keypad_parse_dt(struct device *dev)
{
return NULL;
}
static void samsung_keypad_dt_gpio_free(struct samsung_keypad *keypad)
{
}
#endif
static int __devinit samsung_keypad_probe(struct platform_device *pdev) static int __devinit samsung_keypad_probe(struct platform_device *pdev)
{ {
const struct samsung_keypad_platdata *pdata; const struct samsung_keypad_platdata *pdata;
...@@ -246,7 +363,10 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev) ...@@ -246,7 +363,10 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
unsigned int keymap_size; unsigned int keymap_size;
int error; int error;
pdata = pdev->dev.platform_data; if (pdev->dev.of_node)
pdata = samsung_keypad_parse_dt(&pdev->dev);
else
pdata = pdev->dev.platform_data;
if (!pdata) { if (!pdata) {
dev_err(&pdev->dev, "no platform data defined\n"); dev_err(&pdev->dev, "no platform data defined\n");
return -EINVAL; return -EINVAL;
...@@ -303,6 +423,16 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev) ...@@ -303,6 +423,16 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
keypad->cols = pdata->cols; keypad->cols = pdata->cols;
init_waitqueue_head(&keypad->wait); init_waitqueue_head(&keypad->wait);
if (pdev->dev.of_node) {
#ifdef CONFIG_OF
samsung_keypad_parse_dt_gpio(&pdev->dev, keypad);
keypad->type = of_device_is_compatible(pdev->dev.of_node,
"samsung,s5pv210-keypad");
#endif
} else {
keypad->type = platform_get_device_id(pdev)->driver_data;
}
input_dev->name = pdev->name; input_dev->name = pdev->name;
input_dev->id.bustype = BUS_HOST; input_dev->id.bustype = BUS_HOST;
input_dev->dev.parent = &pdev->dev; input_dev->dev.parent = &pdev->dev;
...@@ -343,12 +473,19 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev) ...@@ -343,12 +473,19 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, pdata->wakeup); device_init_wakeup(&pdev->dev, pdata->wakeup);
platform_set_drvdata(pdev, keypad); platform_set_drvdata(pdev, keypad);
if (pdev->dev.of_node) {
devm_kfree(&pdev->dev, (void *)pdata->keymap_data->keymap);
devm_kfree(&pdev->dev, (void *)pdata->keymap_data);
devm_kfree(&pdev->dev, (void *)pdata);
}
return 0; return 0;
err_free_irq: err_free_irq:
free_irq(keypad->irq, keypad); free_irq(keypad->irq, keypad);
err_put_clk: err_put_clk:
clk_put(keypad->clk); clk_put(keypad->clk);
samsung_keypad_dt_gpio_free(keypad);
err_unmap_base: err_unmap_base:
iounmap(keypad->base); iounmap(keypad->base);
err_free_mem: err_free_mem:
...@@ -374,6 +511,7 @@ static int __devexit samsung_keypad_remove(struct platform_device *pdev) ...@@ -374,6 +511,7 @@ static int __devexit samsung_keypad_remove(struct platform_device *pdev)
free_irq(keypad->irq, keypad); free_irq(keypad->irq, keypad);
clk_put(keypad->clk); clk_put(keypad->clk);
samsung_keypad_dt_gpio_free(keypad);
iounmap(keypad->base); iounmap(keypad->base);
kfree(keypad); kfree(keypad);
...@@ -447,6 +585,17 @@ static const struct dev_pm_ops samsung_keypad_pm_ops = { ...@@ -447,6 +585,17 @@ static const struct dev_pm_ops samsung_keypad_pm_ops = {
}; };
#endif #endif
#ifdef CONFIG_OF
static const struct of_device_id samsung_keypad_dt_match[] = {
{ .compatible = "samsung,s3c6410-keypad" },
{ .compatible = "samsung,s5pv210-keypad" },
{},
};
MODULE_DEVICE_TABLE(of, samsung_keypad_dt_match);
#else
#define samsung_keypad_dt_match NULL
#endif
static struct platform_device_id samsung_keypad_driver_ids[] = { static struct platform_device_id samsung_keypad_driver_ids[] = {
{ {
.name = "samsung-keypad", .name = "samsung-keypad",
...@@ -465,6 +614,7 @@ static struct platform_driver samsung_keypad_driver = { ...@@ -465,6 +614,7 @@ static struct platform_driver samsung_keypad_driver = {
.driver = { .driver = {
.name = "samsung-keypad", .name = "samsung-keypad",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = samsung_keypad_dt_match,
#ifdef CONFIG_PM #ifdef CONFIG_PM
.pm = &samsung_keypad_pm_ops, .pm = &samsung_keypad_pm_ops,
#endif #endif
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/log2.h> #include <linux/log2.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -507,7 +508,13 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) ...@@ -507,7 +508,13 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
goto err_nortc; goto err_nortc;
} }
s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data; #ifdef CONFIG_OF
if (pdev->dev.of_node)
s3c_rtc_cpu_type = of_device_is_compatible(pdev->dev.of_node,
"samsung,s3c6410-rtc") ? TYPE_S3C64XX : TYPE_S3C2410;
else
#endif
s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
/* Check RTC Time */ /* Check RTC Time */
...@@ -629,6 +636,17 @@ static int s3c_rtc_resume(struct platform_device *pdev) ...@@ -629,6 +636,17 @@ static int s3c_rtc_resume(struct platform_device *pdev)
#define s3c_rtc_resume NULL #define s3c_rtc_resume NULL
#endif #endif
#ifdef CONFIG_OF
static const struct of_device_id s3c_rtc_dt_match[] = {
{ .compatible = "samsung,s3c2410-rtc" },
{ .compatible = "samsung,s3c6410-rtc" },
{},
};
MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match);
#else
#define s3c_rtc_dt_match NULL
#endif
static struct platform_device_id s3c_rtc_driver_ids[] = { static struct platform_device_id s3c_rtc_driver_ids[] = {
{ {
.name = "s3c2410-rtc", .name = "s3c2410-rtc",
...@@ -651,6 +669,7 @@ static struct platform_driver s3c_rtc_driver = { ...@@ -651,6 +669,7 @@ static struct platform_driver s3c_rtc_driver = {
.driver = { .driver = {
.name = "s3c-rtc", .name = "s3c-rtc",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = s3c_rtc_dt_match,
}, },
}; };
......
...@@ -462,7 +462,7 @@ config SERIAL_SAMSUNG ...@@ -462,7 +462,7 @@ config SERIAL_SAMSUNG
config SERIAL_SAMSUNG_UARTS_4 config SERIAL_SAMSUNG_UARTS_4
bool bool
depends on ARM && PLAT_SAMSUNG depends on ARM && PLAT_SAMSUNG
default y if CPU_S3C2443 default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442)
help help
Internal node for the common case of 4 Samsung compatible UARTs Internal node for the common case of 4 Samsung compatible UARTs
...@@ -470,7 +470,7 @@ config SERIAL_SAMSUNG_UARTS ...@@ -470,7 +470,7 @@ config SERIAL_SAMSUNG_UARTS
int int
depends on ARM && PLAT_SAMSUNG depends on ARM && PLAT_SAMSUNG
default 6 if ARCH_S5P6450 default 6 if ARCH_S5P6450
default 4 if SERIAL_SAMSUNG_UARTS_4 default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416
default 3 default 3
help help
Select the number of available UART ports for the Samsung S3C Select the number of available UART ports for the Samsung S3C
...@@ -500,46 +500,6 @@ config SERIAL_SAMSUNG_CONSOLE ...@@ -500,46 +500,6 @@ config SERIAL_SAMSUNG_CONSOLE
your boot loader about how to pass options to the kernel at your boot loader about how to pass options to the kernel at
boot time.) boot time.)
config SERIAL_S3C2410
tristate "Samsung S3C2410 Serial port support"
depends on SERIAL_SAMSUNG && CPU_S3C2410
default y if CPU_S3C2410
help
Serial port support for the Samsung S3C2410 SoC
config SERIAL_S3C2412
tristate "Samsung S3C2412/S3C2413 Serial port support"
depends on SERIAL_SAMSUNG && CPU_S3C2412
default y if CPU_S3C2412
help
Serial port support for the Samsung S3C2412 and S3C2413 SoC
config SERIAL_S3C2440
tristate "Samsung S3C2440/S3C2442/S3C2416 Serial port support"
depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442 || CPU_S3C2416)
default y if CPU_S3C2440
default y if CPU_S3C2442
select SERIAL_SAMSUNG_UARTS_4 if CPU_S3C2416
help
Serial port support for the Samsung S3C2440, S3C2416 and S3C2442 SoC
config SERIAL_S3C6400
tristate "Samsung S3C6400/S3C6410/S5P6440/S5P6450/S5PC100 Serial port support"
depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5P6450 || CPU_S5PC100)
select SERIAL_SAMSUNG_UARTS_4
default y
help
Serial port support for the Samsung S3C6400, S3C6410, S5P6440, S5P6450
and S5PC100 SoCs
config SERIAL_S5PV210
tristate "Samsung S5PV210 Serial port support"
depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210 || SOC_EXYNOS4212)
select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210 || SOC_EXYNOS4212)
default y
help
Serial port support for Samsung's S5P Family of SoC's
config SERIAL_SIRFSOC config SERIAL_SIRFSOC
tristate "SiRF SoC Platform Serial port support" tristate "SiRF SoC Platform Serial port support"
depends on ARM && ARCH_PRIMA2 depends on ARM && ARCH_PRIMA2
......
...@@ -40,11 +40,6 @@ obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o ...@@ -40,11 +40,6 @@ obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
obj-$(CONFIG_SERIAL_BFIN) += bfin_uart.o obj-$(CONFIG_SERIAL_BFIN) += bfin_uart.o
obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o
obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o
obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o
obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o
obj-$(CONFIG_SERIAL_MAX3100) += max3100.o obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
obj-$(CONFIG_SERIAL_MAX3107) += max3107.o obj-$(CONFIG_SERIAL_MAX3107) += max3107.o
obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o
......
/*
* Driver for Samsung S3C2410 SoC onboard UARTs.
*
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include "samsung.h"
static int s3c2410_serial_setsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
if (strcmp(clk->name, "uclk") == 0)
ucon |= S3C2410_UCON_UCLK;
else
ucon &= ~S3C2410_UCON_UCLK;
wr_regl(port, S3C2410_UCON, ucon);
return 0;
}
static int s3c2410_serial_getsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
clk->divisor = 1;
clk->name = (ucon & S3C2410_UCON_UCLK) ? "uclk" : "pclk";
return 0;
}
static int s3c2410_serial_resetport(struct uart_port *port,
struct s3c2410_uartcfg *cfg)
{
dbg("s3c2410_serial_resetport: port=%p (%08lx), cfg=%p\n",
port, port->mapbase, cfg);
wr_regl(port, S3C2410_UCON, cfg->ucon);
wr_regl(port, S3C2410_ULCON, cfg->ulcon);
/* reset both fifos */
wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
wr_regl(port, S3C2410_UFCON, cfg->ufcon);
return 0;
}
static struct s3c24xx_uart_info s3c2410_uart_inf = {
.name = "Samsung S3C2410 UART",
.type = PORT_S3C2410,
.fifosize = 16,
.rx_fifomask = S3C2410_UFSTAT_RXMASK,
.rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
.rx_fifofull = S3C2410_UFSTAT_RXFULL,
.tx_fifofull = S3C2410_UFSTAT_TXFULL,
.tx_fifomask = S3C2410_UFSTAT_TXMASK,
.tx_fifoshift = S3C2410_UFSTAT_TXSHIFT,
.get_clksrc = s3c2410_serial_getsource,
.set_clksrc = s3c2410_serial_setsource,
.reset_port = s3c2410_serial_resetport,
};
static int s3c2410_serial_probe(struct platform_device *dev)
{
return s3c24xx_serial_probe(dev, &s3c2410_uart_inf);
}
static struct platform_driver s3c2410_serial_driver = {
.probe = s3c2410_serial_probe,
.remove = __devexit_p(s3c24xx_serial_remove),
.driver = {
.name = "s3c2410-uart",
.owner = THIS_MODULE,
},
};
static int __init s3c2410_serial_init(void)
{
return s3c24xx_serial_init(&s3c2410_serial_driver, &s3c2410_uart_inf);
}
static void __exit s3c2410_serial_exit(void)
{
platform_driver_unregister(&s3c2410_serial_driver);
}
module_init(s3c2410_serial_init);
module_exit(s3c2410_serial_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_DESCRIPTION("Samsung S3C2410 SoC Serial port driver");
MODULE_ALIAS("platform:s3c2410-uart");
/*
* Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs.
*
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include "samsung.h"
static int s3c2412_serial_setsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
ucon &= ~S3C2412_UCON_CLKMASK;
if (strcmp(clk->name, "uclk") == 0)
ucon |= S3C2440_UCON_UCLK;
else if (strcmp(clk->name, "pclk") == 0)
ucon |= S3C2440_UCON_PCLK;
else if (strcmp(clk->name, "usysclk") == 0)
ucon |= S3C2412_UCON_USYSCLK;
else {
printk(KERN_ERR "unknown clock source %s\n", clk->name);
return -EINVAL;
}
wr_regl(port, S3C2410_UCON, ucon);
return 0;
}
static int s3c2412_serial_getsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
switch (ucon & S3C2412_UCON_CLKMASK) {
case S3C2412_UCON_UCLK:
clk->divisor = 1;
clk->name = "uclk";
break;
case S3C2412_UCON_PCLK:
case S3C2412_UCON_PCLK2:
clk->divisor = 1;
clk->name = "pclk";
break;
case S3C2412_UCON_USYSCLK:
clk->divisor = 1;
clk->name = "usysclk";
break;
}
return 0;
}
static int s3c2412_serial_resetport(struct uart_port *port,
struct s3c2410_uartcfg *cfg)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
dbg("%s: port=%p (%08lx), cfg=%p\n",
__func__, port, port->mapbase, cfg);
/* ensure we don't change the clock settings... */
ucon &= S3C2412_UCON_CLKMASK;
wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
wr_regl(port, S3C2410_ULCON, cfg->ulcon);
/* reset both fifos */
wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
wr_regl(port, S3C2410_UFCON, cfg->ufcon);
return 0;
}
static struct s3c24xx_uart_info s3c2412_uart_inf = {
.name = "Samsung S3C2412 UART",
.type = PORT_S3C2412,
.fifosize = 64,
.has_divslot = 1,
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
.rx_fifofull = S3C2440_UFSTAT_RXFULL,
.tx_fifofull = S3C2440_UFSTAT_TXFULL,
.tx_fifomask = S3C2440_UFSTAT_TXMASK,
.tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
.get_clksrc = s3c2412_serial_getsource,
.set_clksrc = s3c2412_serial_setsource,
.reset_port = s3c2412_serial_resetport,
};
/* device management */
static int s3c2412_serial_probe(struct platform_device *dev)
{
dbg("s3c2440_serial_probe: dev=%p\n", dev);
return s3c24xx_serial_probe(dev, &s3c2412_uart_inf);
}
static struct platform_driver s3c2412_serial_driver = {
.probe = s3c2412_serial_probe,
.remove = __devexit_p(s3c24xx_serial_remove),
.driver = {
.name = "s3c2412-uart",
.owner = THIS_MODULE,
},
};
static inline int s3c2412_serial_init(void)
{
return s3c24xx_serial_init(&s3c2412_serial_driver, &s3c2412_uart_inf);
}
static inline void s3c2412_serial_exit(void)
{
platform_driver_unregister(&s3c2412_serial_driver);
}
module_init(s3c2412_serial_init);
module_exit(s3c2412_serial_exit);
MODULE_DESCRIPTION("Samsung S3C2412,S3C2413 SoC Serial port driver");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:s3c2412-uart");
/*
* Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs.
*
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include "samsung.h"
static int s3c2440_serial_setsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
/* todo - proper fclk<>nonfclk switch. */
ucon &= ~S3C2440_UCON_CLKMASK;
if (strcmp(clk->name, "uclk") == 0)
ucon |= S3C2440_UCON_UCLK;
else if (strcmp(clk->name, "pclk") == 0)
ucon |= S3C2440_UCON_PCLK;
else if (strcmp(clk->name, "fclk") == 0)
ucon |= S3C2440_UCON_FCLK;
else {
printk(KERN_ERR "unknown clock source %s\n", clk->name);
return -EINVAL;
}
wr_regl(port, S3C2410_UCON, ucon);
return 0;
}
static int s3c2440_serial_getsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
unsigned long ucon0, ucon1, ucon2;
switch (ucon & S3C2440_UCON_CLKMASK) {
case S3C2440_UCON_UCLK:
clk->divisor = 1;
clk->name = "uclk";
break;
case S3C2440_UCON_PCLK:
case S3C2440_UCON_PCLK2:
clk->divisor = 1;
clk->name = "pclk";
break;
case S3C2440_UCON_FCLK:
/* the fun of calculating the uart divisors on
* the s3c2440 */
ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
printk("ucons: %08lx, %08lx, %08lx\n", ucon0, ucon1, ucon2);
ucon0 &= S3C2440_UCON0_DIVMASK;
ucon1 &= S3C2440_UCON1_DIVMASK;
ucon2 &= S3C2440_UCON2_DIVMASK;
if (ucon0 != 0) {
clk->divisor = ucon0 >> S3C2440_UCON_DIVSHIFT;
clk->divisor += 6;
} else if (ucon1 != 0) {
clk->divisor = ucon1 >> S3C2440_UCON_DIVSHIFT;
clk->divisor += 21;
} else if (ucon2 != 0) {
clk->divisor = ucon2 >> S3C2440_UCON_DIVSHIFT;
clk->divisor += 36;
} else {
/* manual calims 44, seems to be 9 */
clk->divisor = 9;
}
clk->name = "fclk";
break;
}
return 0;
}
static int s3c2440_serial_resetport(struct uart_port *port,
struct s3c2410_uartcfg *cfg)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
dbg("s3c2440_serial_resetport: port=%p (%08lx), cfg=%p\n",
port, port->mapbase, cfg);
/* ensure we don't change the clock settings... */
ucon &= (S3C2440_UCON0_DIVMASK | (3<<10));
wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
wr_regl(port, S3C2410_ULCON, cfg->ulcon);
/* reset both fifos */
wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
wr_regl(port, S3C2410_UFCON, cfg->ufcon);
return 0;
}
static struct s3c24xx_uart_info s3c2440_uart_inf = {
.name = "Samsung S3C2440 UART",
.type = PORT_S3C2440,
.fifosize = 64,
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
.rx_fifofull = S3C2440_UFSTAT_RXFULL,
.tx_fifofull = S3C2440_UFSTAT_TXFULL,
.tx_fifomask = S3C2440_UFSTAT_TXMASK,
.tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
.get_clksrc = s3c2440_serial_getsource,
.set_clksrc = s3c2440_serial_setsource,
.reset_port = s3c2440_serial_resetport,
};
/* device management */
static int s3c2440_serial_probe(struct platform_device *dev)
{
dbg("s3c2440_serial_probe: dev=%p\n", dev);
return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);
}
static struct platform_driver s3c2440_serial_driver = {
.probe = s3c2440_serial_probe,
.remove = __devexit_p(s3c24xx_serial_remove),
.driver = {
.name = "s3c2440-uart",
.owner = THIS_MODULE,
},
};
static int __init s3c2440_serial_init(void)
{
return s3c24xx_serial_init(&s3c2440_serial_driver, &s3c2440_uart_inf);
}
static void __exit s3c2440_serial_exit(void)
{
platform_driver_unregister(&s3c2440_serial_driver);
}
module_init(s3c2440_serial_init);
module_exit(s3c2440_serial_exit);
MODULE_DESCRIPTION("Samsung S3C2440,S3C2442 SoC Serial port driver");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:s3c2440-uart");
/*
* Driver for Samsung S3C6400 and S3C6410 SoC onboard UARTs.
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <plat/regs-serial.h>
#include "samsung.h"
static int s3c6400_serial_setsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
if (strcmp(clk->name, "uclk0") == 0) {
ucon &= ~S3C6400_UCON_CLKMASK;
ucon |= S3C6400_UCON_UCLK0;
} else if (strcmp(clk->name, "uclk1") == 0)
ucon |= S3C6400_UCON_UCLK1;
else if (strcmp(clk->name, "pclk") == 0) {
/* See notes about transitioning from UCLK to PCLK */
ucon &= ~S3C6400_UCON_UCLK0;
} else {
printk(KERN_ERR "unknown clock source %s\n", clk->name);
return -EINVAL;
}
wr_regl(port, S3C2410_UCON, ucon);
return 0;
}
static int s3c6400_serial_getsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
u32 ucon = rd_regl(port, S3C2410_UCON);
clk->divisor = 1;
switch (ucon & S3C6400_UCON_CLKMASK) {
case S3C6400_UCON_UCLK0:
clk->name = "uclk0";
break;
case S3C6400_UCON_UCLK1:
clk->name = "uclk1";
break;
case S3C6400_UCON_PCLK:
case S3C6400_UCON_PCLK2:
clk->name = "pclk";
break;
}
return 0;
}
static int s3c6400_serial_resetport(struct uart_port *port,
struct s3c2410_uartcfg *cfg)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
dbg("s3c6400_serial_resetport: port=%p (%08lx), cfg=%p\n",
port, port->mapbase, cfg);
/* ensure we don't change the clock settings... */
ucon &= S3C6400_UCON_CLKMASK;
wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
wr_regl(port, S3C2410_ULCON, cfg->ulcon);
/* reset both fifos */
wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
wr_regl(port, S3C2410_UFCON, cfg->ufcon);
return 0;
}
static struct s3c24xx_uart_info s3c6400_uart_inf = {
.name = "Samsung S3C6400 UART",
.type = PORT_S3C6400,
.fifosize = 64,
.has_divslot = 1,
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
.rx_fifofull = S3C2440_UFSTAT_RXFULL,
.tx_fifofull = S3C2440_UFSTAT_TXFULL,
.tx_fifomask = S3C2440_UFSTAT_TXMASK,
.tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
.get_clksrc = s3c6400_serial_getsource,
.set_clksrc = s3c6400_serial_setsource,
.reset_port = s3c6400_serial_resetport,
};
/* device management */
static int s3c6400_serial_probe(struct platform_device *dev)
{
dbg("s3c6400_serial_probe: dev=%p\n", dev);
return s3c24xx_serial_probe(dev, &s3c6400_uart_inf);
}
static struct platform_driver s3c6400_serial_driver = {
.probe = s3c6400_serial_probe,
.remove = __devexit_p(s3c24xx_serial_remove),
.driver = {
.name = "s3c6400-uart",
.owner = THIS_MODULE,
},
};
static int __init s3c6400_serial_init(void)
{
return s3c24xx_serial_init(&s3c6400_serial_driver, &s3c6400_uart_inf);
}
static void __exit s3c6400_serial_exit(void)
{
platform_driver_unregister(&s3c6400_serial_driver);
}
module_init(s3c6400_serial_init);
module_exit(s3c6400_serial_exit);
MODULE_DESCRIPTION("Samsung S3C6400,S3C6410 SoC Serial port driver");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:s3c6400-uart");
/*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* Based on drivers/serial/s3c6400.c
*
* Driver for Samsung S5PV210 SoC UARTs.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <plat/regs-serial.h>
#include "samsung.h"
static int s5pv210_serial_setsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
struct s3c2410_uartcfg *cfg = port->dev->platform_data;
unsigned long ucon = rd_regl(port, S3C2410_UCON);
if (cfg->flags & NO_NEED_CHECK_CLKSRC)
return 0;
if (strcmp(clk->name, "pclk") == 0)
ucon &= ~S5PV210_UCON_CLKMASK;
else if (strcmp(clk->name, "uclk1") == 0)
ucon |= S5PV210_UCON_CLKMASK;
else {
printk(KERN_ERR "unknown clock source %s\n", clk->name);
return -EINVAL;
}
wr_regl(port, S3C2410_UCON, ucon);
return 0;
}
static int s5pv210_serial_getsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
struct s3c2410_uartcfg *cfg = port->dev->platform_data;
u32 ucon = rd_regl(port, S3C2410_UCON);
clk->divisor = 1;
if (cfg->flags & NO_NEED_CHECK_CLKSRC)
return 0;
switch (ucon & S5PV210_UCON_CLKMASK) {
case S5PV210_UCON_PCLK:
clk->name = "pclk";
break;
case S5PV210_UCON_UCLK:
clk->name = "uclk1";
break;
}
return 0;
}
static int s5pv210_serial_resetport(struct uart_port *port,
struct s3c2410_uartcfg *cfg)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
ucon &= S5PV210_UCON_CLKMASK;
wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
wr_regl(port, S3C2410_ULCON, cfg->ulcon);
/* reset both fifos */
wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
wr_regl(port, S3C2410_UFCON, cfg->ufcon);
/* It is need to delay When reset FIFO register */
udelay(1);
return 0;
}
#define S5PV210_UART_DEFAULT_INFO(fifo_size) \
.name = "Samsung S5PV210 UART0", \
.type = PORT_S3C6400, \
.fifosize = fifo_size, \
.has_divslot = 1, \
.rx_fifomask = S5PV210_UFSTAT_RXMASK, \
.rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \
.rx_fifofull = S5PV210_UFSTAT_RXFULL, \
.tx_fifofull = S5PV210_UFSTAT_TXFULL, \
.tx_fifomask = S5PV210_UFSTAT_TXMASK, \
.tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \
.get_clksrc = s5pv210_serial_getsource, \
.set_clksrc = s5pv210_serial_setsource, \
.reset_port = s5pv210_serial_resetport
static struct s3c24xx_uart_info s5p_port_fifo256 = {
S5PV210_UART_DEFAULT_INFO(256),
};
static struct s3c24xx_uart_info s5p_port_fifo64 = {
S5PV210_UART_DEFAULT_INFO(64),
};
static struct s3c24xx_uart_info s5p_port_fifo16 = {
S5PV210_UART_DEFAULT_INFO(16),
};
static struct s3c24xx_uart_info *s5p_uart_inf[] = {
[0] = &s5p_port_fifo256,
[1] = &s5p_port_fifo64,
[2] = &s5p_port_fifo16,
[3] = &s5p_port_fifo16,
};
/* device management */
static int s5p_serial_probe(struct platform_device *pdev)
{
return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]);
}
static struct platform_driver s5p_serial_driver = {
.probe = s5p_serial_probe,
.remove = __devexit_p(s3c24xx_serial_remove),
.driver = {
.name = "s5pv210-uart",
.owner = THIS_MODULE,
},
};
static int __init s5p_serial_init(void)
{
return s3c24xx_serial_init(&s5p_serial_driver, *s5p_uart_inf);
}
static void __exit s5p_serial_exit(void)
{
platform_driver_unregister(&s5p_serial_driver);
}
module_init(s5p_serial_init);
module_exit(s5p_serial_exit);
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:s5pv210-uart");
MODULE_DESCRIPTION("Samsung S5PV210 UART Driver support");
MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/of.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -49,6 +50,7 @@ ...@@ -49,6 +50,7 @@
#include <mach/map.h> #include <mach/map.h>
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <plat/clock.h>
#include "samsung.h" #include "samsung.h"
...@@ -190,10 +192,13 @@ static inline struct s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *p ...@@ -190,10 +192,13 @@ static inline struct s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *p
static inline struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port) static inline struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port)
{ {
struct s3c24xx_uart_port *ourport;
if (port->dev == NULL) if (port->dev == NULL)
return NULL; return NULL;
return (struct s3c2410_uartcfg *)port->dev->platform_data; ourport = container_of(port, struct s3c24xx_uart_port, port);
return ourport->cfg;
} }
static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport, static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
...@@ -202,7 +207,7 @@ static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport, ...@@ -202,7 +207,7 @@ static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
struct s3c24xx_uart_info *info = ourport->info; struct s3c24xx_uart_info *info = ourport->info;
if (ufstat & info->rx_fifofull) if (ufstat & info->rx_fifofull)
return info->fifosize; return ourport->port.fifosize;
return (ufstat & info->rx_fifomask) >> info->rx_fifoshift; return (ufstat & info->rx_fifomask) >> info->rx_fifoshift;
} }
...@@ -555,154 +560,98 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, ...@@ -555,154 +560,98 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
* *
*/ */
#define MAX_CLK_NAME_LENGTH 15
#define MAX_CLKS (8) static inline int s3c24xx_serial_getsource(struct uart_port *port)
static struct s3c24xx_uart_clksrc tmp_clksrc = {
.name = "pclk",
.min_baud = 0,
.max_baud = 0,
.divisor = 1,
};
static inline int
s3c24xx_serial_getsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
{ {
struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
unsigned int ucon;
return (info->get_clksrc)(port, c); if (info->num_clks == 1)
} return 0;
static inline int
s3c24xx_serial_setsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
{
struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
return (info->set_clksrc)(port, c); ucon = rd_regl(port, S3C2410_UCON);
ucon &= info->clksel_mask;
return ucon >> info->clksel_shift;
} }
struct baud_calc { static void s3c24xx_serial_setsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clksrc; unsigned int clk_sel)
unsigned int calc;
unsigned int divslot;
unsigned int quot;
struct clk *src;
};
static int s3c24xx_serial_calcbaud(struct baud_calc *calc,
struct uart_port *port,
struct s3c24xx_uart_clksrc *clksrc,
unsigned int baud)
{ {
struct s3c24xx_uart_port *ourport = to_ourport(port); struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
unsigned long rate; unsigned int ucon;
calc->src = clk_get(port->dev, clksrc->name);
if (calc->src == NULL || IS_ERR(calc->src))
return 0;
rate = clk_get_rate(calc->src);
rate /= clksrc->divisor;
calc->clksrc = clksrc; if (info->num_clks == 1)
return;
if (ourport->info->has_divslot) { ucon = rd_regl(port, S3C2410_UCON);
unsigned long div = rate / baud; if ((ucon & info->clksel_mask) >> info->clksel_shift == clk_sel)
return;
/* The UDIVSLOT register on the newer UARTs allows us to
* get a divisor adjustment of 1/16th on the baud clock.
*
* We don't keep the UDIVSLOT value (the 16ths we calculated
* by not multiplying the baud by 16) as it is easy enough
* to recalculate.
*/
calc->quot = div / 16;
calc->calc = rate / div;
} else {
calc->quot = (rate + (8 * baud)) / (16 * baud);
calc->calc = (rate / (calc->quot * 16));
}
calc->quot--; ucon &= ~info->clksel_mask;
return 1; ucon |= clk_sel << info->clksel_shift;
wr_regl(port, S3C2410_UCON, ucon);
} }
static unsigned int s3c24xx_serial_getclk(struct uart_port *port, static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport,
struct s3c24xx_uart_clksrc **clksrc, unsigned int req_baud, struct clk **best_clk,
struct clk **clk, unsigned int *clk_num)
unsigned int baud)
{ {
struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); struct s3c24xx_uart_info *info = ourport->info;
struct s3c24xx_uart_clksrc *clkp; struct clk *clk;
struct baud_calc res[MAX_CLKS]; unsigned long rate;
struct baud_calc *resptr, *best, *sptr; unsigned int cnt, baud, quot, clk_sel, best_quot = 0;
int i; char clkname[MAX_CLK_NAME_LENGTH];
int calc_deviation, deviation = (1 << 30) - 1;
clkp = cfg->clocks;
best = NULL; *best_clk = NULL;
clk_sel = (ourport->cfg->clk_sel) ? ourport->cfg->clk_sel :
if (cfg->clocks_size < 2) { ourport->info->def_clk_sel;
if (cfg->clocks_size == 0) for (cnt = 0; cnt < info->num_clks; cnt++) {
clkp = &tmp_clksrc; if (!(clk_sel & (1 << cnt)))
continue;
/* check to see if we're sourcing fclk, and if so we're
* going to have to update the clock source sprintf(clkname, "clk_uart_baud%d", cnt);
*/ clk = clk_get(ourport->port.dev, clkname);
if (IS_ERR_OR_NULL(clk))
if (strcmp(clkp->name, "fclk") == 0) { continue;
struct s3c24xx_uart_clksrc src;
rate = clk_get_rate(clk);
s3c24xx_serial_getsource(port, &src); if (!rate)
continue;
/* check that the port already using fclk, and if
* not, then re-select fclk if (ourport->info->has_divslot) {
unsigned long div = rate / req_baud;
/* The UDIVSLOT register on the newer UARTs allows us to
* get a divisor adjustment of 1/16th on the baud clock.
*
* We don't keep the UDIVSLOT value (the 16ths we
* calculated by not multiplying the baud by 16) as it
* is easy enough to recalculate.
*/ */
if (strcmp(src.name, clkp->name) == 0) { quot = div / 16;
s3c24xx_serial_setsource(port, clkp); baud = rate / div;
s3c24xx_serial_getsource(port, &src); } else {
} quot = (rate + (8 * req_baud)) / (16 * req_baud);
baud = rate / (quot * 16);
clkp->divisor = src.divisor;
}
s3c24xx_serial_calcbaud(res, port, clkp, baud);
best = res;
resptr = best + 1;
} else {
resptr = res;
for (i = 0; i < cfg->clocks_size; i++, clkp++) {
if (s3c24xx_serial_calcbaud(resptr, port, clkp, baud))
resptr++;
} }
} quot--;
/* ok, we now need to select the best clock we found */
if (!best) {
unsigned int deviation = (1<<30)|((1<<30)-1);
int calc_deviation;
for (sptr = res; sptr < resptr; sptr++) { calc_deviation = req_baud - baud;
calc_deviation = baud - sptr->calc; if (calc_deviation < 0)
if (calc_deviation < 0) calc_deviation = -calc_deviation;
calc_deviation = -calc_deviation;
if (calc_deviation < deviation) { if (calc_deviation < deviation) {
best = sptr; *best_clk = clk;
deviation = calc_deviation; best_quot = quot;
} *clk_num = cnt;
deviation = calc_deviation;
} }
} }
/* store results to pass back */ return best_quot;
*clksrc = best->clksrc;
*clk = best->src;
return best->quot;
} }
/* udivslot_table[] /* udivslot_table[]
...@@ -735,10 +684,9 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, ...@@ -735,10 +684,9 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
{ {
struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
struct s3c24xx_uart_port *ourport = to_ourport(port); struct s3c24xx_uart_port *ourport = to_ourport(port);
struct s3c24xx_uart_clksrc *clksrc = NULL;
struct clk *clk = NULL; struct clk *clk = NULL;
unsigned long flags; unsigned long flags;
unsigned int baud, quot; unsigned int baud, quot, clk_sel = 0;
unsigned int ulcon; unsigned int ulcon;
unsigned int umcon; unsigned int umcon;
unsigned int udivslot = 0; unsigned int udivslot = 0;
...@@ -754,17 +702,16 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, ...@@ -754,17 +702,16 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
*/ */
baud = uart_get_baud_rate(port, termios, old, 0, 115200*8); baud = uart_get_baud_rate(port, termios, old, 0, 115200*8);
quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel);
if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
quot = port->custom_divisor; quot = port->custom_divisor;
else if (!clk)
quot = s3c24xx_serial_getclk(port, &clksrc, &clk, baud); return;
/* check to see if we need to change clock source */ /* check to see if we need to change clock source */
if (ourport->clksrc != clksrc || ourport->baudclk != clk) { if (ourport->baudclk != clk) {
dbg("selecting clock %p\n", clk); s3c24xx_serial_setsource(port, clk_sel);
s3c24xx_serial_setsource(port, clksrc);
if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) { if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) {
clk_disable(ourport->baudclk); clk_disable(ourport->baudclk);
...@@ -773,7 +720,6 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, ...@@ -773,7 +720,6 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
clk_enable(clk); clk_enable(clk);
ourport->clksrc = clksrc;
ourport->baudclk = clk; ourport->baudclk = clk;
ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0;
} }
...@@ -1020,16 +966,29 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS ...@@ -1020,16 +966,29 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS
/* s3c24xx_serial_resetport /* s3c24xx_serial_resetport
* *
* wrapper to call the specific reset for this port (reset the fifos * reset the fifos and other the settings.
* and the settings)
*/ */
static inline int s3c24xx_serial_resetport(struct uart_port *port, static void s3c24xx_serial_resetport(struct uart_port *port,
struct s3c2410_uartcfg *cfg) struct s3c2410_uartcfg *cfg)
{ {
struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
unsigned long ucon = rd_regl(port, S3C2410_UCON);
unsigned int ucon_mask;
ucon_mask = info->clksel_mask;
if (info->type == PORT_S3C2440)
ucon_mask |= S3C2440_UCON0_DIVMASK;
return (info->reset_port)(port, cfg); ucon &= ucon_mask;
wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
/* reset both fifos */
wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
wr_regl(port, S3C2410_UFCON, cfg->ufcon);
/* some delay is required after fifo reset */
udelay(1);
} }
...@@ -1121,11 +1080,10 @@ static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *p ...@@ -1121,11 +1080,10 @@ static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *p
*/ */
static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
struct s3c24xx_uart_info *info,
struct platform_device *platdev) struct platform_device *platdev)
{ {
struct uart_port *port = &ourport->port; struct uart_port *port = &ourport->port;
struct s3c2410_uartcfg *cfg; struct s3c2410_uartcfg *cfg = ourport->cfg;
struct resource *res; struct resource *res;
int ret; int ret;
...@@ -1134,30 +1092,16 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, ...@@ -1134,30 +1092,16 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
if (platdev == NULL) if (platdev == NULL)
return -ENODEV; return -ENODEV;
cfg = s3c24xx_dev_to_cfg(&platdev->dev);
if (port->mapbase != 0) if (port->mapbase != 0)
return 0; return 0;
if (cfg->hwport > CONFIG_SERIAL_SAMSUNG_UARTS) {
printk(KERN_ERR "%s: port %d bigger than %d\n", __func__,
cfg->hwport, CONFIG_SERIAL_SAMSUNG_UARTS);
return -ERANGE;
}
/* setup info for port */ /* setup info for port */
port->dev = &platdev->dev; port->dev = &platdev->dev;
ourport->info = info;
/* Startup sequence is different for s3c64xx and higher SoC's */ /* Startup sequence is different for s3c64xx and higher SoC's */
if (s3c24xx_serial_has_interrupt_mask(port)) if (s3c24xx_serial_has_interrupt_mask(port))
s3c24xx_serial_ops.startup = s3c64xx_serial_startup; s3c24xx_serial_ops.startup = s3c64xx_serial_startup;
/* copy the info in from provided structure */
ourport->port.fifosize = info->fifosize;
dbg("s3c24xx_serial_init_port: %p (hw %d)...\n", port, cfg->hwport);
port->uartclk = 1; port->uartclk = 1;
if (cfg->uart_flags & UPF_CONS_FLOW) { if (cfg->uart_flags & UPF_CONS_FLOW) {
...@@ -1215,43 +1159,74 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev, ...@@ -1215,43 +1159,74 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev,
struct uart_port *port = s3c24xx_dev_to_port(dev); struct uart_port *port = s3c24xx_dev_to_port(dev);
struct s3c24xx_uart_port *ourport = to_ourport(port); struct s3c24xx_uart_port *ourport = to_ourport(port);
return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->clksrc->name); return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->baudclk->name);
} }
static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL);
/* Device driver serial port probe */ /* Device driver serial port probe */
static const struct of_device_id s3c24xx_uart_dt_match[];
static int probe_index; static int probe_index;
int s3c24xx_serial_probe(struct platform_device *dev, static inline struct s3c24xx_serial_drv_data *s3c24xx_get_driver_data(
struct s3c24xx_uart_info *info) struct platform_device *pdev)
{
#ifdef CONFIG_OF
if (pdev->dev.of_node) {
const struct of_device_id *match;
match = of_match_node(s3c24xx_uart_dt_match, pdev->dev.of_node);
return (struct s3c24xx_serial_drv_data *)match->data;
}
#endif
return (struct s3c24xx_serial_drv_data *)
platform_get_device_id(pdev)->driver_data;
}
static int s3c24xx_serial_probe(struct platform_device *pdev)
{ {
struct s3c24xx_uart_port *ourport; struct s3c24xx_uart_port *ourport;
int ret; int ret;
dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, probe_index); dbg("s3c24xx_serial_probe(%p) %d\n", pdev, probe_index);
ourport = &s3c24xx_serial_ports[probe_index]; ourport = &s3c24xx_serial_ports[probe_index];
ourport->drv_data = s3c24xx_get_driver_data(pdev);
if (!ourport->drv_data) {
dev_err(&pdev->dev, "could not find driver data\n");
return -ENODEV;
}
ourport->info = ourport->drv_data->info;
ourport->cfg = (pdev->dev.platform_data) ?
(struct s3c2410_uartcfg *)pdev->dev.platform_data :
ourport->drv_data->def_cfg;
ourport->port.fifosize = (ourport->info->fifosize) ?
ourport->info->fifosize :
ourport->drv_data->fifosize[probe_index];
probe_index++; probe_index++;
dbg("%s: initialising port %p...\n", __func__, ourport); dbg("%s: initialising port %p...\n", __func__, ourport);
ret = s3c24xx_serial_init_port(ourport, info, dev); ret = s3c24xx_serial_init_port(ourport, pdev);
if (ret < 0) if (ret < 0)
goto probe_err; goto probe_err;
dbg("%s: adding port\n", __func__); dbg("%s: adding port\n", __func__);
uart_add_one_port(&s3c24xx_uart_drv, &ourport->port); uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
platform_set_drvdata(dev, &ourport->port); platform_set_drvdata(pdev, &ourport->port);
ret = device_create_file(&dev->dev, &dev_attr_clock_source); ret = device_create_file(&pdev->dev, &dev_attr_clock_source);
if (ret < 0) if (ret < 0)
printk(KERN_ERR "%s: failed to add clksrc attr.\n", __func__); dev_err(&pdev->dev, "failed to add clock source attr.\n");
ret = s3c24xx_serial_cpufreq_register(ourport); ret = s3c24xx_serial_cpufreq_register(ourport);
if (ret < 0) if (ret < 0)
dev_err(&dev->dev, "failed to add cpufreq notifier\n"); dev_err(&pdev->dev, "failed to add cpufreq notifier\n");
return 0; return 0;
...@@ -1259,9 +1234,7 @@ int s3c24xx_serial_probe(struct platform_device *dev, ...@@ -1259,9 +1234,7 @@ int s3c24xx_serial_probe(struct platform_device *dev,
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(s3c24xx_serial_probe); static int __devexit s3c24xx_serial_remove(struct platform_device *dev)
int __devexit s3c24xx_serial_remove(struct platform_device *dev)
{ {
struct uart_port *port = s3c24xx_dev_to_port(&dev->dev); struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
...@@ -1274,8 +1247,6 @@ int __devexit s3c24xx_serial_remove(struct platform_device *dev) ...@@ -1274,8 +1247,6 @@ int __devexit s3c24xx_serial_remove(struct platform_device *dev)
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(s3c24xx_serial_remove);
/* UART power management code */ /* UART power management code */
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int s3c24xx_serial_suspend(struct device *dev) static int s3c24xx_serial_suspend(struct device *dev)
...@@ -1315,41 +1286,6 @@ static const struct dev_pm_ops s3c24xx_serial_pm_ops = { ...@@ -1315,41 +1286,6 @@ static const struct dev_pm_ops s3c24xx_serial_pm_ops = {
#define SERIAL_SAMSUNG_PM_OPS NULL #define SERIAL_SAMSUNG_PM_OPS NULL
#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM_SLEEP */
int s3c24xx_serial_init(struct platform_driver *drv,
struct s3c24xx_uart_info *info)
{
dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
drv->driver.pm = SERIAL_SAMSUNG_PM_OPS;
return platform_driver_register(drv);
}
EXPORT_SYMBOL_GPL(s3c24xx_serial_init);
/* module initialisation code */
static int __init s3c24xx_serial_modinit(void)
{
int ret;
ret = uart_register_driver(&s3c24xx_uart_drv);
if (ret < 0) {
printk(KERN_ERR "failed to register UART driver\n");
return -1;
}
return 0;
}
static void __exit s3c24xx_serial_modexit(void)
{
uart_unregister_driver(&s3c24xx_uart_drv);
}
module_init(s3c24xx_serial_modinit);
module_exit(s3c24xx_serial_modexit);
/* Console code */ /* Console code */
#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
...@@ -1395,12 +1331,13 @@ static void __init ...@@ -1395,12 +1331,13 @@ static void __init
s3c24xx_serial_get_options(struct uart_port *port, int *baud, s3c24xx_serial_get_options(struct uart_port *port, int *baud,
int *parity, int *bits) int *parity, int *bits)
{ {
struct s3c24xx_uart_clksrc clksrc;
struct clk *clk; struct clk *clk;
unsigned int ulcon; unsigned int ulcon;
unsigned int ucon; unsigned int ucon;
unsigned int ubrdiv; unsigned int ubrdiv;
unsigned long rate; unsigned long rate;
unsigned int clk_sel;
char clk_name[MAX_CLK_NAME_LENGTH];
ulcon = rd_regl(port, S3C2410_ULCON); ulcon = rd_regl(port, S3C2410_ULCON);
ucon = rd_regl(port, S3C2410_UCON); ucon = rd_regl(port, S3C2410_UCON);
...@@ -1445,44 +1382,21 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud, ...@@ -1445,44 +1382,21 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud,
/* now calculate the baud rate */ /* now calculate the baud rate */
s3c24xx_serial_getsource(port, &clksrc); clk_sel = s3c24xx_serial_getsource(port);
sprintf(clk_name, "clk_uart_baud%d", clk_sel);
clk = clk_get(port->dev, clksrc.name); clk = clk_get(port->dev, clk_name);
if (!IS_ERR(clk) && clk != NULL) if (!IS_ERR(clk) && clk != NULL)
rate = clk_get_rate(clk) / clksrc.divisor; rate = clk_get_rate(clk);
else else
rate = 1; rate = 1;
*baud = rate / (16 * (ubrdiv + 1)); *baud = rate / (16 * (ubrdiv + 1));
dbg("calculated baud %d\n", *baud); dbg("calculated baud %d\n", *baud);
} }
} }
/* s3c24xx_serial_init_ports
*
* initialise the serial ports from the machine provided initialisation
* data.
*/
static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info **info)
{
struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports;
struct platform_device **platdev_ptr;
int i;
dbg("s3c24xx_serial_init_ports: initialising ports...\n");
platdev_ptr = s3c24xx_uart_devs;
for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++, ptr++, platdev_ptr++) {
s3c24xx_serial_init_port(ptr, info[i], *platdev_ptr);
}
return 0;
}
static int __init static int __init
s3c24xx_serial_console_setup(struct console *co, char *options) s3c24xx_serial_console_setup(struct console *co, char *options)
{ {
...@@ -1526,11 +1440,6 @@ s3c24xx_serial_console_setup(struct console *co, char *options) ...@@ -1526,11 +1440,6 @@ s3c24xx_serial_console_setup(struct console *co, char *options)
return uart_set_options(port, co, baud, parity, bits, flow); return uart_set_options(port, co, baud, parity, bits, flow);
} }
/* s3c24xx_serial_initconsole
*
* initialise the console from one of the uart drivers
*/
static struct console s3c24xx_serial_console = { static struct console s3c24xx_serial_console = {
.name = S3C24XX_SERIAL_NAME, .name = S3C24XX_SERIAL_NAME,
.device = uart_console_device, .device = uart_console_device,
...@@ -1540,34 +1449,250 @@ static struct console s3c24xx_serial_console = { ...@@ -1540,34 +1449,250 @@ static struct console s3c24xx_serial_console = {
.setup = s3c24xx_serial_console_setup, .setup = s3c24xx_serial_console_setup,
.data = &s3c24xx_uart_drv, .data = &s3c24xx_uart_drv,
}; };
#endif /* CONFIG_SERIAL_SAMSUNG_CONSOLE */
int s3c24xx_serial_initconsole(struct platform_driver *drv, #ifdef CONFIG_CPU_S3C2410
struct s3c24xx_uart_info **info) static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = {
.info = &(struct s3c24xx_uart_info) {
.name = "Samsung S3C2410 UART",
.type = PORT_S3C2410,
.fifosize = 16,
.rx_fifomask = S3C2410_UFSTAT_RXMASK,
.rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
.rx_fifofull = S3C2410_UFSTAT_RXFULL,
.tx_fifofull = S3C2410_UFSTAT_TXFULL,
.tx_fifomask = S3C2410_UFSTAT_TXMASK,
.tx_fifoshift = S3C2410_UFSTAT_TXSHIFT,
.def_clk_sel = S3C2410_UCON_CLKSEL0,
.num_clks = 2,
.clksel_mask = S3C2410_UCON_CLKMASK,
.clksel_shift = S3C2410_UCON_CLKSHIFT,
},
.def_cfg = &(struct s3c2410_uartcfg) {
.ucon = S3C2410_UCON_DEFAULT,
.ufcon = S3C2410_UFCON_DEFAULT,
},
};
#define S3C2410_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2410_serial_drv_data)
#else
#define S3C2410_SERIAL_DRV_DATA (kernel_ulong_t)NULL
#endif
{ #ifdef CONFIG_CPU_S3C2412
struct platform_device *dev = s3c24xx_uart_devs[0]; static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = {
.info = &(struct s3c24xx_uart_info) {
.name = "Samsung S3C2412 UART",
.type = PORT_S3C2412,
.fifosize = 64,
.has_divslot = 1,
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
.rx_fifofull = S3C2440_UFSTAT_RXFULL,
.tx_fifofull = S3C2440_UFSTAT_TXFULL,
.tx_fifomask = S3C2440_UFSTAT_TXMASK,
.tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
.def_clk_sel = S3C2410_UCON_CLKSEL2,
.num_clks = 4,
.clksel_mask = S3C2412_UCON_CLKMASK,
.clksel_shift = S3C2412_UCON_CLKSHIFT,
},
.def_cfg = &(struct s3c2410_uartcfg) {
.ucon = S3C2410_UCON_DEFAULT,
.ufcon = S3C2410_UFCON_DEFAULT,
},
};
#define S3C2412_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2412_serial_drv_data)
#else
#define S3C2412_SERIAL_DRV_DATA (kernel_ulong_t)NULL
#endif
dbg("s3c24xx_serial_initconsole\n"); #if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2416) || \
defined(CONFIG_CPU_S3C2443)
static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
.info = &(struct s3c24xx_uart_info) {
.name = "Samsung S3C2440 UART",
.type = PORT_S3C2440,
.fifosize = 64,
.has_divslot = 1,
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
.rx_fifofull = S3C2440_UFSTAT_RXFULL,
.tx_fifofull = S3C2440_UFSTAT_TXFULL,
.tx_fifomask = S3C2440_UFSTAT_TXMASK,
.tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
.def_clk_sel = S3C2410_UCON_CLKSEL2,
.num_clks = 4,
.clksel_mask = S3C2412_UCON_CLKMASK,
.clksel_shift = S3C2412_UCON_CLKSHIFT,
},
.def_cfg = &(struct s3c2410_uartcfg) {
.ucon = S3C2410_UCON_DEFAULT,
.ufcon = S3C2410_UFCON_DEFAULT,
},
};
#define S3C2440_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2440_serial_drv_data)
#else
#define S3C2440_SERIAL_DRV_DATA (kernel_ulong_t)NULL
#endif
/* select driver based on the cpu */ #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) || \
defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) || \
defined(CONFIG_CPU_S5PC100)
static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
.info = &(struct s3c24xx_uart_info) {
.name = "Samsung S3C6400 UART",
.type = PORT_S3C6400,
.fifosize = 64,
.has_divslot = 1,
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
.rx_fifofull = S3C2440_UFSTAT_RXFULL,
.tx_fifofull = S3C2440_UFSTAT_TXFULL,
.tx_fifomask = S3C2440_UFSTAT_TXMASK,
.tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
.def_clk_sel = S3C2410_UCON_CLKSEL2,
.num_clks = 4,
.clksel_mask = S3C6400_UCON_CLKMASK,
.clksel_shift = S3C6400_UCON_CLKSHIFT,
},
.def_cfg = &(struct s3c2410_uartcfg) {
.ucon = S3C2410_UCON_DEFAULT,
.ufcon = S3C2410_UFCON_DEFAULT,
},
};
#define S3C6400_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c6400_serial_drv_data)
#else
#define S3C6400_SERIAL_DRV_DATA (kernel_ulong_t)NULL
#endif
if (dev == NULL) { #ifdef CONFIG_CPU_S5PV210
printk(KERN_ERR "s3c24xx: no devices for console init\n"); static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
return 0; .info = &(struct s3c24xx_uart_info) {
} .name = "Samsung S5PV210 UART",
.type = PORT_S3C6400,
.has_divslot = 1,
.rx_fifomask = S5PV210_UFSTAT_RXMASK,
.rx_fifoshift = S5PV210_UFSTAT_RXSHIFT,
.rx_fifofull = S5PV210_UFSTAT_RXFULL,
.tx_fifofull = S5PV210_UFSTAT_TXFULL,
.tx_fifomask = S5PV210_UFSTAT_TXMASK,
.tx_fifoshift = S5PV210_UFSTAT_TXSHIFT,
.def_clk_sel = S3C2410_UCON_CLKSEL0,
.num_clks = 2,
.clksel_mask = S5PV210_UCON_CLKMASK,
.clksel_shift = S5PV210_UCON_CLKSHIFT,
},
.def_cfg = &(struct s3c2410_uartcfg) {
.ucon = S5PV210_UCON_DEFAULT,
.ufcon = S5PV210_UFCON_DEFAULT,
},
.fifosize = { 256, 64, 16, 16 },
};
#define S5PV210_SERIAL_DRV_DATA ((kernel_ulong_t)&s5pv210_serial_drv_data)
#else
#define S5PV210_SERIAL_DRV_DATA (kernel_ulong_t)NULL
#endif
if (strcmp(dev->name, drv->driver.name) != 0) #ifdef CONFIG_CPU_EXYNOS4210
return 0; static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
.info = &(struct s3c24xx_uart_info) {
.name = "Samsung Exynos4 UART",
.type = PORT_S3C6400,
.has_divslot = 1,
.rx_fifomask = S5PV210_UFSTAT_RXMASK,
.rx_fifoshift = S5PV210_UFSTAT_RXSHIFT,
.rx_fifofull = S5PV210_UFSTAT_RXFULL,
.tx_fifofull = S5PV210_UFSTAT_TXFULL,
.tx_fifomask = S5PV210_UFSTAT_TXMASK,
.tx_fifoshift = S5PV210_UFSTAT_TXSHIFT,
.def_clk_sel = S3C2410_UCON_CLKSEL0,
.num_clks = 1,
.clksel_mask = 0,
.clksel_shift = 0,
},
.def_cfg = &(struct s3c2410_uartcfg) {
.ucon = S5PV210_UCON_DEFAULT,
.ufcon = S5PV210_UFCON_DEFAULT,
.has_fracval = 1,
},
.fifosize = { 256, 64, 16, 16 },
};
#define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data)
#else
#define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL
#endif
s3c24xx_serial_console.data = &s3c24xx_uart_drv; static struct platform_device_id s3c24xx_serial_driver_ids[] = {
s3c24xx_serial_init_ports(info); {
.name = "s3c2410-uart",
.driver_data = S3C2410_SERIAL_DRV_DATA,
}, {
.name = "s3c2412-uart",
.driver_data = S3C2412_SERIAL_DRV_DATA,
}, {
.name = "s3c2440-uart",
.driver_data = S3C2440_SERIAL_DRV_DATA,
}, {
.name = "s3c6400-uart",
.driver_data = S3C6400_SERIAL_DRV_DATA,
}, {
.name = "s5pv210-uart",
.driver_data = S5PV210_SERIAL_DRV_DATA,
}, {
.name = "exynos4210-uart",
.driver_data = EXYNOS4210_SERIAL_DRV_DATA,
},
{ },
};
MODULE_DEVICE_TABLE(platform, s3c24xx_serial_driver_ids);
register_console(&s3c24xx_serial_console); #ifdef CONFIG_OF
return 0; static const struct of_device_id s3c24xx_uart_dt_match[] = {
{ .compatible = "samsung,exynos4210-uart",
.data = (void *)EXYNOS4210_SERIAL_DRV_DATA },
{},
};
MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
#else
#define s3c24xx_uart_dt_match NULL
#endif
static struct platform_driver samsung_serial_driver = {
.probe = s3c24xx_serial_probe,
.remove = __devexit_p(s3c24xx_serial_remove),
.id_table = s3c24xx_serial_driver_ids,
.driver = {
.name = "samsung-uart",
.owner = THIS_MODULE,
.pm = SERIAL_SAMSUNG_PM_OPS,
.of_match_table = s3c24xx_uart_dt_match,
},
};
/* module initialisation code */
static int __init s3c24xx_serial_modinit(void)
{
int ret;
ret = uart_register_driver(&s3c24xx_uart_drv);
if (ret < 0) {
printk(KERN_ERR "failed to register UART driver\n");
return -1;
}
return platform_driver_register(&samsung_serial_driver);
} }
#endif /* CONFIG_SERIAL_SAMSUNG_CONSOLE */ static void __exit s3c24xx_serial_modexit(void)
{
uart_unregister_driver(&s3c24xx_uart_drv);
}
module_init(s3c24xx_serial_modinit);
module_exit(s3c24xx_serial_modexit);
MODULE_ALIAS("platform:samsung-uart");
MODULE_DESCRIPTION("Samsung SoC Serial port driver"); MODULE_DESCRIPTION("Samsung SoC Serial port driver");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -19,20 +19,25 @@ struct s3c24xx_uart_info { ...@@ -19,20 +19,25 @@ struct s3c24xx_uart_info {
unsigned long tx_fifomask; unsigned long tx_fifomask;
unsigned long tx_fifoshift; unsigned long tx_fifoshift;
unsigned long tx_fifofull; unsigned long tx_fifofull;
unsigned int def_clk_sel;
unsigned long num_clks;
unsigned long clksel_mask;
unsigned long clksel_shift;
/* uart port features */ /* uart port features */
unsigned int has_divslot:1; unsigned int has_divslot:1;
/* clock source control */
int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
int (*set_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
/* uart controls */ /* uart controls */
int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *); int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *);
}; };
struct s3c24xx_serial_drv_data {
struct s3c24xx_uart_info *info;
struct s3c2410_uartcfg *def_cfg;
unsigned int fifosize[CONFIG_SERIAL_SAMSUNG_UARTS];
};
struct s3c24xx_uart_port { struct s3c24xx_uart_port {
unsigned char rx_claimed; unsigned char rx_claimed;
unsigned char tx_claimed; unsigned char tx_claimed;
...@@ -43,10 +48,13 @@ struct s3c24xx_uart_port { ...@@ -43,10 +48,13 @@ struct s3c24xx_uart_port {
unsigned int tx_irq; unsigned int tx_irq;
struct s3c24xx_uart_info *info; struct s3c24xx_uart_info *info;
struct s3c24xx_uart_clksrc *clksrc;
struct clk *clk; struct clk *clk;
struct clk *baudclk; struct clk *baudclk;
struct uart_port port; struct uart_port port;
struct s3c24xx_serial_drv_data *drv_data;
/* reference to platform data */
struct s3c2410_uartcfg *cfg;
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
struct notifier_block freq_transition; struct notifier_block freq_transition;
...@@ -56,7 +64,6 @@ struct s3c24xx_uart_port { ...@@ -56,7 +64,6 @@ struct s3c24xx_uart_port {
/* conversion functions */ /* conversion functions */
#define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev) #define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev)
#define s3c24xx_dev_to_cfg(__dev) (struct s3c2410_uartcfg *)((__dev)->platform_data)
/* register access controls */ /* register access controls */
...@@ -69,17 +76,6 @@ struct s3c24xx_uart_port { ...@@ -69,17 +76,6 @@ struct s3c24xx_uart_port {
#define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg)) #define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg))
#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg)) #define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg))
extern int s3c24xx_serial_probe(struct platform_device *dev,
struct s3c24xx_uart_info *uart);
extern int __devexit s3c24xx_serial_remove(struct platform_device *dev);
extern int s3c24xx_serial_initconsole(struct platform_driver *drv,
struct s3c24xx_uart_info **uart);
extern int s3c24xx_serial_init(struct platform_driver *drv,
struct s3c24xx_uart_info *info);
#ifdef CONFIG_SERIAL_SAMSUNG_DEBUG #ifdef CONFIG_SERIAL_SAMSUNG_DEBUG
extern void printascii(const char *); extern void printascii(const char *);
......
...@@ -21,7 +21,12 @@ ...@@ -21,7 +21,12 @@
#include <linux/platform_data/tegra_usb.h> #include <linux/platform_data/tegra_usb.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/usb/otg.h> #include <linux/usb/otg.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <mach/usb_phy.h> #include <mach/usb_phy.h>
#include <mach/iomap.h>
#define TEGRA_USB_DMA_ALIGN 32 #define TEGRA_USB_DMA_ALIGN 32
...@@ -574,6 +579,35 @@ static const struct hc_driver tegra_ehci_hc_driver = { ...@@ -574,6 +579,35 @@ static const struct hc_driver tegra_ehci_hc_driver = {
.port_handed_over = ehci_port_handed_over, .port_handed_over = ehci_port_handed_over,
}; };
static int setup_vbus_gpio(struct platform_device *pdev)
{
int err = 0;
int gpio;
if (!pdev->dev.of_node)
return 0;
gpio = of_get_named_gpio(pdev->dev.of_node, "nvidia,vbus-gpio", 0);
if (!gpio_is_valid(gpio))
return 0;
err = gpio_request(gpio, "vbus_gpio");
if (err) {
dev_err(&pdev->dev, "can't request vbus gpio %d", gpio);
return err;
}
err = gpio_direction_output(gpio, 1);
if (err) {
dev_err(&pdev->dev, "can't enable vbus\n");
return err;
}
gpio_set_value(gpio, 1);
return err;
}
static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32);
static int tegra_ehci_probe(struct platform_device *pdev) static int tegra_ehci_probe(struct platform_device *pdev)
{ {
struct resource *res; struct resource *res;
...@@ -590,6 +624,15 @@ static int tegra_ehci_probe(struct platform_device *pdev) ...@@ -590,6 +624,15 @@ static int tegra_ehci_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
/* Right now device-tree probed devices don't get dma_mask set.
* Since shared usb code relies on it, set it here for now.
* Once we have dma capability bindings this can go away.
*/
if (!pdev->dev.dma_mask)
pdev->dev.dma_mask = &tegra_ehci_dma_mask;
setup_vbus_gpio(pdev);
tegra = kzalloc(sizeof(struct tegra_ehci_hcd), GFP_KERNEL); tegra = kzalloc(sizeof(struct tegra_ehci_hcd), GFP_KERNEL);
if (!tegra) if (!tegra)
return -ENOMEM; return -ENOMEM;
...@@ -640,6 +683,28 @@ static int tegra_ehci_probe(struct platform_device *pdev) ...@@ -640,6 +683,28 @@ static int tegra_ehci_probe(struct platform_device *pdev)
goto fail_io; goto fail_io;
} }
/* This is pretty ugly and needs to be fixed when we do only
* device-tree probing. Old code relies on the platform_device
* numbering that we lack for device-tree-instantiated devices.
*/
if (instance < 0) {
switch (res->start) {
case TEGRA_USB_BASE:
instance = 0;
break;
case TEGRA_USB2_BASE:
instance = 1;
break;
case TEGRA_USB3_BASE:
instance = 2;
break;
default:
err = -ENODEV;
dev_err(&pdev->dev, "unknown usb instance\n");
goto fail_phy;
}
}
tegra->phy = tegra_usb_phy_open(instance, hcd->regs, pdata->phy_config, tegra->phy = tegra_usb_phy_open(instance, hcd->regs, pdata->phy_config,
TEGRA_USB_PHY_MODE_HOST); TEGRA_USB_PHY_MODE_HOST);
if (IS_ERR(tegra->phy)) { if (IS_ERR(tegra->phy)) {
...@@ -773,6 +838,11 @@ static void tegra_ehci_hcd_shutdown(struct platform_device *pdev) ...@@ -773,6 +838,11 @@ static void tegra_ehci_hcd_shutdown(struct platform_device *pdev)
hcd->driver->shutdown(hcd); hcd->driver->shutdown(hcd);
} }
static struct of_device_id tegra_ehci_of_match[] __devinitdata = {
{ .compatible = "nvidia,tegra20-ehci", },
{ },
};
static struct platform_driver tegra_ehci_driver = { static struct platform_driver tegra_ehci_driver = {
.probe = tegra_ehci_probe, .probe = tegra_ehci_probe,
.remove = tegra_ehci_remove, .remove = tegra_ehci_remove,
...@@ -783,5 +853,6 @@ static struct platform_driver tegra_ehci_driver = { ...@@ -783,5 +853,6 @@ static struct platform_driver tegra_ehci_driver = {
.shutdown = tegra_ehci_hcd_shutdown, .shutdown = tegra_ehci_hcd_shutdown,
.driver = { .driver = {
.name = "tegra-ehci", .name = "tegra-ehci",
.of_match_table = tegra_ehci_of_match,
} }
}; };
...@@ -12,17 +12,9 @@ ...@@ -12,17 +12,9 @@
#ifndef __AMBA_PL330_H_ #ifndef __AMBA_PL330_H_
#define __AMBA_PL330_H_ #define __AMBA_PL330_H_
#include <linux/dmaengine.h>
#include <asm/hardware/pl330.h> #include <asm/hardware/pl330.h>
struct dma_pl330_peri {
/*
* Peri_Req i/f of the DMAC that is
* peripheral could be reached from.
*/
u8 peri_id; /* specific dma id */
enum pl330_reqtype rqtype;
};
struct dma_pl330_platdata { struct dma_pl330_platdata {
/* /*
* Number of valid peripherals connected to DMAC. * Number of valid peripherals connected to DMAC.
...@@ -33,9 +25,12 @@ struct dma_pl330_platdata { ...@@ -33,9 +25,12 @@ struct dma_pl330_platdata {
*/ */
u8 nr_valid_peri; u8 nr_valid_peri;
/* Array of valid peripherals */ /* Array of valid peripherals */
struct dma_pl330_peri *peri; u8 *peri_id;
/* Operational capabilities */
dma_cap_mask_t cap_mask;
/* Bytes to allocate for MC buffer */ /* Bytes to allocate for MC buffer */
unsigned mcbuf_sz; unsigned mcbuf_sz;
}; };
extern bool pl330_filter(struct dma_chan *chan, void *param);
#endif /* __AMBA_PL330_H_ */ #endif /* __AMBA_PL330_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment