Commit dec8e461 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arc-v3.13-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc

Pull second set of ARC changes from Vineet Gupta:
 - Support for Perf from Mischa
 - Enabling GPIO/Pinctrl drivers for Abilis TB10x platform
 - New defconfig for buildroot

* tag 'arc-v3.13-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc:
  ARC: [plat-arcfpga] Add defconfig without initramfs location
  ARC: perf: ARC 700 PMU doesn't support sampling events
  ARC: Add documentation on DT binding for ARC700 PMU
  ARC: Add perf support for ARC700 cores
  ARC: [TB10x] Updates for GPIO and pinctrl
parents 806dace6 cd5dfd0e
* ARC Performance Monitor Unit
The ARC 700 can be configured with a pipeline performance monitor for counting
CPU and cache events like cache misses and hits.
Note that:
* ARC 700 refers to a family of ARC processor cores;
- There is only one type of PMU available for the whole family;
- The PMU may support different sets of events; supported events are probed
at boot time, as required by the reference manual.
* The ARC 700 PMU does not support interrupts; although HW events may be
counted, the HW events themselves cannot serve as a trigger for a sample.
Required properties:
- compatible : should contain
"snps,arc700-pmu"
Example:
pmu {
compatible = "snps,arc700-pmu";
};
...@@ -43,124 +43,124 @@ ahb_clk: clkdiv_ahb { ...@@ -43,124 +43,124 @@ ahb_clk: clkdiv_ahb {
iomux: iomux@FF10601c { iomux: iomux@FF10601c {
/* Port 1 */ /* Port 1 */
pctl_tsin_s0: pctl-tsin-s0 { /* Serial TS-in 0 */ pctl_tsin_s0: pctl-tsin-s0 { /* Serial TS-in 0 */
pingrp = "mis0_pins"; abilis,function = "mis0";
}; };
pctl_tsin_s1: pctl-tsin-s1 { /* Serial TS-in 1 */ pctl_tsin_s1: pctl-tsin-s1 { /* Serial TS-in 1 */
pingrp = "mis1_pins"; abilis,function = "mis1";
}; };
pctl_gpio_a: pctl-gpio-a { /* GPIO bank A */ pctl_gpio_a: pctl-gpio-a { /* GPIO bank A */
pingrp = "gpioa_pins"; abilis,function = "gpioa";
}; };
pctl_tsin_p1: pctl-tsin-p1 { /* Parallel TS-in 1 */ pctl_tsin_p1: pctl-tsin-p1 { /* Parallel TS-in 1 */
pingrp = "mip1_pins"; abilis,function = "mip1";
}; };
/* Port 2 */ /* Port 2 */
pctl_tsin_s2: pctl-tsin-s2 { /* Serial TS-in 2 */ pctl_tsin_s2: pctl-tsin-s2 { /* Serial TS-in 2 */
pingrp = "mis2_pins"; abilis,function = "mis2";
}; };
pctl_tsin_s3: pctl-tsin-s3 { /* Serial TS-in 3 */ pctl_tsin_s3: pctl-tsin-s3 { /* Serial TS-in 3 */
pingrp = "mis3_pins"; abilis,function = "mis3";
}; };
pctl_gpio_c: pctl-gpio-c { /* GPIO bank C */ pctl_gpio_c: pctl-gpio-c { /* GPIO bank C */
pingrp = "gpioc_pins"; abilis,function = "gpioc";
}; };
pctl_tsin_p3: pctl-tsin-p3 { /* Parallel TS-in 3 */ pctl_tsin_p3: pctl-tsin-p3 { /* Parallel TS-in 3 */
pingrp = "mip3_pins"; abilis,function = "mip3";
}; };
/* Port 3 */ /* Port 3 */
pctl_tsin_s4: pctl-tsin-s4 { /* Serial TS-in 4 */ pctl_tsin_s4: pctl-tsin-s4 { /* Serial TS-in 4 */
pingrp = "mis4_pins"; abilis,function = "mis4";
}; };
pctl_tsin_s5: pctl-tsin-s5 { /* Serial TS-in 5 */ pctl_tsin_s5: pctl-tsin-s5 { /* Serial TS-in 5 */
pingrp = "mis5_pins"; abilis,function = "mis5";
}; };
pctl_gpio_e: pctl-gpio-e { /* GPIO bank E */ pctl_gpio_e: pctl-gpio-e { /* GPIO bank E */
pingrp = "gpioe_pins"; abilis,function = "gpioe";
}; };
pctl_tsin_p5: pctl-tsin-p5 { /* Parallel TS-in 5 */ pctl_tsin_p5: pctl-tsin-p5 { /* Parallel TS-in 5 */
pingrp = "mip5_pins"; abilis,function = "mip5";
}; };
/* Port 4 */ /* Port 4 */
pctl_tsin_s6: pctl-tsin-s6 { /* Serial TS-in 6 */ pctl_tsin_s6: pctl-tsin-s6 { /* Serial TS-in 6 */
pingrp = "mis6_pins"; abilis,function = "mis6";
}; };
pctl_tsin_s7: pctl-tsin-s7 { /* Serial TS-in 7 */ pctl_tsin_s7: pctl-tsin-s7 { /* Serial TS-in 7 */
pingrp = "mis7_pins"; abilis,function = "mis7";
}; };
pctl_gpio_g: pctl-gpio-g { /* GPIO bank G */ pctl_gpio_g: pctl-gpio-g { /* GPIO bank G */
pingrp = "gpiog_pins"; abilis,function = "gpiog";
}; };
pctl_tsin_p7: pctl-tsin-p7 { /* Parallel TS-in 7 */ pctl_tsin_p7: pctl-tsin-p7 { /* Parallel TS-in 7 */
pingrp = "mip7_pins"; abilis,function = "mip7";
}; };
/* Port 5 */ /* Port 5 */
pctl_gpio_j: pctl-gpio-j { /* GPIO bank J */ pctl_gpio_j: pctl-gpio-j { /* GPIO bank J */
pingrp = "gpioj_pins"; abilis,function = "gpioj";
}; };
pctl_gpio_k: pctl-gpio-k { /* GPIO bank K */ pctl_gpio_k: pctl-gpio-k { /* GPIO bank K */
pingrp = "gpiok_pins"; abilis,function = "gpiok";
}; };
pctl_ciplus: pctl-ciplus { /* CI+ interface */ pctl_ciplus: pctl-ciplus { /* CI+ interface */
pingrp = "ciplus_pins"; abilis,function = "ciplus";
}; };
pctl_mcard: pctl-mcard { /* M-Card interface */ pctl_mcard: pctl-mcard { /* M-Card interface */
pingrp = "mcard_pins"; abilis,function = "mcard";
}; };
/* Port 6 */ /* Port 6 */
pctl_tsout_p: pctl-tsout-p { /* Parallel TS-out */ pctl_tsout_p: pctl-tsout-p { /* Parallel TS-out */
pingrp = "mop_pins"; abilis,function = "mop";
}; };
pctl_tsout_s0: pctl-tsout-s0 { /* Serial TS-out 0 */ pctl_tsout_s0: pctl-tsout-s0 { /* Serial TS-out 0 */
pingrp = "mos0_pins"; abilis,function = "mos0";
}; };
pctl_tsout_s1: pctl-tsout-s1 { /* Serial TS-out 1 */ pctl_tsout_s1: pctl-tsout-s1 { /* Serial TS-out 1 */
pingrp = "mos1_pins"; abilis,function = "mos1";
}; };
pctl_tsout_s2: pctl-tsout-s2 { /* Serial TS-out 2 */ pctl_tsout_s2: pctl-tsout-s2 { /* Serial TS-out 2 */
pingrp = "mos2_pins"; abilis,function = "mos2";
}; };
pctl_tsout_s3: pctl-tsout-s3 { /* Serial TS-out 3 */ pctl_tsout_s3: pctl-tsout-s3 { /* Serial TS-out 3 */
pingrp = "mos3_pins"; abilis,function = "mos3";
}; };
/* Port 7 */ /* Port 7 */
pctl_uart0: pctl-uart0 { /* UART 0 */ pctl_uart0: pctl-uart0 { /* UART 0 */
pingrp = "uart0_pins"; abilis,function = "uart0";
}; };
pctl_uart1: pctl-uart1 { /* UART 1 */ pctl_uart1: pctl-uart1 { /* UART 1 */
pingrp = "uart1_pins"; abilis,function = "uart1";
}; };
pctl_gpio_l: pctl-gpio-l { /* GPIO bank L */ pctl_gpio_l: pctl-gpio-l { /* GPIO bank L */
pingrp = "gpiol_pins"; abilis,function = "gpiol";
}; };
pctl_gpio_m: pctl-gpio-m { /* GPIO bank M */ pctl_gpio_m: pctl-gpio-m { /* GPIO bank M */
pingrp = "gpiom_pins"; abilis,function = "gpiom";
}; };
/* Port 8 */ /* Port 8 */
pctl_spi3: pctl-spi3 { pctl_spi3: pctl-spi3 {
pingrp = "spi3_pins"; abilis,function = "spi3";
}; };
/* Port 9 */ /* Port 9 */
pctl_spi1: pctl-spi1 { pctl_spi1: pctl-spi1 {
pingrp = "spi1_pins"; abilis,function = "spi1";
}; };
pctl_gpio_n: pctl-gpio-n { pctl_gpio_n: pctl-gpio-n {
pingrp = "gpion_pins"; abilis,function = "gpion";
}; };
/* Unmuxed GPIOs */ /* Unmuxed GPIOs */
pctl_gpio_b: pctl-gpio-b { pctl_gpio_b: pctl-gpio-b {
pingrp = "gpiob_pins"; abilis,function = "gpiob";
}; };
pctl_gpio_d: pctl-gpio-d { pctl_gpio_d: pctl-gpio-d {
pingrp = "gpiod_pins"; abilis,function = "gpiod";
}; };
pctl_gpio_f: pctl-gpio-f { pctl_gpio_f: pctl-gpio-f {
pingrp = "gpiof_pins"; abilis,function = "gpiof";
}; };
pctl_gpio_h: pctl-gpio-h { pctl_gpio_h: pctl-gpio-h {
pingrp = "gpioh_pins"; abilis,function = "gpioh";
}; };
pctl_gpio_i: pctl-gpio-i { pctl_gpio_i: pctl-gpio-i {
pingrp = "gpioi_pins"; abilis,function = "gpioi";
}; };
}; };
...@@ -172,9 +172,10 @@ gpioa: gpio@FF140000 { ...@@ -172,9 +172,10 @@ gpioa: gpio@FF140000 {
interrupts = <27 2>; interrupts = <27 2>;
reg = <0xFF140000 0x1000>; reg = <0xFF140000 0x1000>;
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <2>;
gpio-base = <0>; abilis,ngpio = <3>;
gpio-pins = <&pctl_gpio_a>; gpio-ranges = <&iomux 0 0 0>;
gpio-ranges-group-names = "gpioa";
}; };
gpiob: gpio@FF141000 { gpiob: gpio@FF141000 {
compatible = "abilis,tb10x-gpio"; compatible = "abilis,tb10x-gpio";
...@@ -184,9 +185,10 @@ gpiob: gpio@FF141000 { ...@@ -184,9 +185,10 @@ gpiob: gpio@FF141000 {
interrupts = <27 2>; interrupts = <27 2>;
reg = <0xFF141000 0x1000>; reg = <0xFF141000 0x1000>;
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <2>;
gpio-base = <3>; abilis,ngpio = <2>;
gpio-pins = <&pctl_gpio_b>; gpio-ranges = <&iomux 0 0 0>;
gpio-ranges-group-names = "gpiob";
}; };
gpioc: gpio@FF142000 { gpioc: gpio@FF142000 {
compatible = "abilis,tb10x-gpio"; compatible = "abilis,tb10x-gpio";
...@@ -196,9 +198,10 @@ gpioc: gpio@FF142000 { ...@@ -196,9 +198,10 @@ gpioc: gpio@FF142000 {
interrupts = <27 2>; interrupts = <27 2>;
reg = <0xFF142000 0x1000>; reg = <0xFF142000 0x1000>;
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <2>;
gpio-base = <5>; abilis,ngpio = <3>;
gpio-pins = <&pctl_gpio_c>; gpio-ranges = <&iomux 0 0 0>;
gpio-ranges-group-names = "gpioc";
}; };
gpiod: gpio@FF143000 { gpiod: gpio@FF143000 {
compatible = "abilis,tb10x-gpio"; compatible = "abilis,tb10x-gpio";
...@@ -208,9 +211,10 @@ gpiod: gpio@FF143000 { ...@@ -208,9 +211,10 @@ gpiod: gpio@FF143000 {
interrupts = <27 2>; interrupts = <27 2>;
reg = <0xFF143000 0x1000>; reg = <0xFF143000 0x1000>;
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <2>;
gpio-base = <8>; abilis,ngpio = <2>;
gpio-pins = <&pctl_gpio_d>; gpio-ranges = <&iomux 0 0 0>;
gpio-ranges-group-names = "gpiod";
}; };
gpioe: gpio@FF144000 { gpioe: gpio@FF144000 {
compatible = "abilis,tb10x-gpio"; compatible = "abilis,tb10x-gpio";
...@@ -220,9 +224,10 @@ gpioe: gpio@FF144000 { ...@@ -220,9 +224,10 @@ gpioe: gpio@FF144000 {
interrupts = <27 2>; interrupts = <27 2>;
reg = <0xFF144000 0x1000>; reg = <0xFF144000 0x1000>;
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <2>;
gpio-base = <10>; abilis,ngpio = <3>;
gpio-pins = <&pctl_gpio_e>; gpio-ranges = <&iomux 0 0 0>;
gpio-ranges-group-names = "gpioe";
}; };
gpiof: gpio@FF145000 { gpiof: gpio@FF145000 {
compatible = "abilis,tb10x-gpio"; compatible = "abilis,tb10x-gpio";
...@@ -232,9 +237,10 @@ gpiof: gpio@FF145000 { ...@@ -232,9 +237,10 @@ gpiof: gpio@FF145000 {
interrupts = <27 2>; interrupts = <27 2>;
reg = <0xFF145000 0x1000>; reg = <0xFF145000 0x1000>;
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <2>;
gpio-base = <13>; abilis,ngpio = <2>;
gpio-pins = <&pctl_gpio_f>; gpio-ranges = <&iomux 0 0 0>;
gpio-ranges-group-names = "gpiof";
}; };
gpiog: gpio@FF146000 { gpiog: gpio@FF146000 {
compatible = "abilis,tb10x-gpio"; compatible = "abilis,tb10x-gpio";
...@@ -244,9 +250,10 @@ gpiog: gpio@FF146000 { ...@@ -244,9 +250,10 @@ gpiog: gpio@FF146000 {
interrupts = <27 2>; interrupts = <27 2>;
reg = <0xFF146000 0x1000>; reg = <0xFF146000 0x1000>;
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <2>;
gpio-base = <15>; abilis,ngpio = <3>;
gpio-pins = <&pctl_gpio_g>; gpio-ranges = <&iomux 0 0 0>;
gpio-ranges-group-names = "gpiog";
}; };
gpioh: gpio@FF147000 { gpioh: gpio@FF147000 {
compatible = "abilis,tb10x-gpio"; compatible = "abilis,tb10x-gpio";
...@@ -256,9 +263,10 @@ gpioh: gpio@FF147000 { ...@@ -256,9 +263,10 @@ gpioh: gpio@FF147000 {
interrupts = <27 2>; interrupts = <27 2>;
reg = <0xFF147000 0x1000>; reg = <0xFF147000 0x1000>;
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <2>;
gpio-base = <18>; abilis,ngpio = <2>;
gpio-pins = <&pctl_gpio_h>; gpio-ranges = <&iomux 0 0 0>;
gpio-ranges-group-names = "gpioh";
}; };
gpioi: gpio@FF148000 { gpioi: gpio@FF148000 {
compatible = "abilis,tb10x-gpio"; compatible = "abilis,tb10x-gpio";
...@@ -268,9 +276,10 @@ gpioi: gpio@FF148000 { ...@@ -268,9 +276,10 @@ gpioi: gpio@FF148000 {
interrupts = <27 2>; interrupts = <27 2>;
reg = <0xFF148000 0x1000>; reg = <0xFF148000 0x1000>;
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <2>;
gpio-base = <20>; abilis,ngpio = <12>;
gpio-pins = <&pctl_gpio_i>; gpio-ranges = <&iomux 0 0 0>;
gpio-ranges-group-names = "gpioi";
}; };
gpioj: gpio@FF149000 { gpioj: gpio@FF149000 {
compatible = "abilis,tb10x-gpio"; compatible = "abilis,tb10x-gpio";
...@@ -280,9 +289,10 @@ gpioj: gpio@FF149000 { ...@@ -280,9 +289,10 @@ gpioj: gpio@FF149000 {
interrupts = <27 2>; interrupts = <27 2>;
reg = <0xFF149000 0x1000>; reg = <0xFF149000 0x1000>;
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <2>;
gpio-base = <32>; abilis,ngpio = <32>;
gpio-pins = <&pctl_gpio_j>; gpio-ranges = <&iomux 0 0 0>;
gpio-ranges-group-names = "gpioj";
}; };
gpiok: gpio@FF14a000 { gpiok: gpio@FF14a000 {
compatible = "abilis,tb10x-gpio"; compatible = "abilis,tb10x-gpio";
...@@ -292,9 +302,10 @@ gpiok: gpio@FF14a000 { ...@@ -292,9 +302,10 @@ gpiok: gpio@FF14a000 {
interrupts = <27 2>; interrupts = <27 2>;
reg = <0xFF14A000 0x1000>; reg = <0xFF14A000 0x1000>;
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <2>;
gpio-base = <64>; abilis,ngpio = <22>;
gpio-pins = <&pctl_gpio_k>; gpio-ranges = <&iomux 0 0 0>;
gpio-ranges-group-names = "gpiok";
}; };
gpiol: gpio@FF14b000 { gpiol: gpio@FF14b000 {
compatible = "abilis,tb10x-gpio"; compatible = "abilis,tb10x-gpio";
...@@ -304,9 +315,10 @@ gpiol: gpio@FF14b000 { ...@@ -304,9 +315,10 @@ gpiol: gpio@FF14b000 {
interrupts = <27 2>; interrupts = <27 2>;
reg = <0xFF14B000 0x1000>; reg = <0xFF14B000 0x1000>;
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <2>;
gpio-base = <86>; abilis,ngpio = <4>;
gpio-pins = <&pctl_gpio_l>; gpio-ranges = <&iomux 0 0 0>;
gpio-ranges-group-names = "gpiol";
}; };
gpiom: gpio@FF14c000 { gpiom: gpio@FF14c000 {
compatible = "abilis,tb10x-gpio"; compatible = "abilis,tb10x-gpio";
...@@ -316,9 +328,10 @@ gpiom: gpio@FF14c000 { ...@@ -316,9 +328,10 @@ gpiom: gpio@FF14c000 {
interrupts = <27 2>; interrupts = <27 2>;
reg = <0xFF14C000 0x1000>; reg = <0xFF14C000 0x1000>;
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <2>;
gpio-base = <90>; abilis,ngpio = <4>;
gpio-pins = <&pctl_gpio_m>; gpio-ranges = <&iomux 0 0 0>;
gpio-ranges-group-names = "gpiom";
}; };
gpion: gpio@FF14d000 { gpion: gpio@FF14d000 {
compatible = "abilis,tb10x-gpio"; compatible = "abilis,tb10x-gpio";
...@@ -328,9 +341,10 @@ gpion: gpio@FF14d000 { ...@@ -328,9 +341,10 @@ gpion: gpio@FF14d000 {
interrupts = <27 2>; interrupts = <27 2>;
reg = <0xFF14D000 0x1000>; reg = <0xFF14D000 0x1000>;
gpio-controller; gpio-controller;
#gpio-cells = <1>; #gpio-cells = <2>;
gpio-base = <94>; abilis,ngpio = <5>;
gpio-pins = <&pctl_gpio_n>; gpio-ranges = <&iomux 0 0 0>;
gpio-ranges-group-names = "gpion";
}; };
}; };
}; };
...@@ -64,62 +64,62 @@ leds { ...@@ -64,62 +64,62 @@ leds {
compatible = "gpio-leds"; compatible = "gpio-leds";
power { power {
label = "Power"; label = "Power";
gpios = <&gpioi 0>; gpios = <&gpioi 0 0>;
linux,default-trigger = "default-on"; linux,default-trigger = "default-on";
}; };
heartbeat { heartbeat {
label = "Heartbeat"; label = "Heartbeat";
gpios = <&gpioi 1>; gpios = <&gpioi 1 0>;
linux,default-trigger = "heartbeat"; linux,default-trigger = "heartbeat";
}; };
led2 { led2 {
label = "LED2"; label = "LED2";
gpios = <&gpioi 2>; gpios = <&gpioi 2 0>;
default-state = "off"; default-state = "off";
}; };
led3 { led3 {
label = "LED3"; label = "LED3";
gpios = <&gpioi 3>; gpios = <&gpioi 3 0>;
default-state = "off"; default-state = "off";
}; };
led4 { led4 {
label = "LED4"; label = "LED4";
gpios = <&gpioi 4>; gpios = <&gpioi 4 0>;
default-state = "off"; default-state = "off";
}; };
led5 { led5 {
label = "LED5"; label = "LED5";
gpios = <&gpioi 5>; gpios = <&gpioi 5 0>;
default-state = "off"; default-state = "off";
}; };
led6 { led6 {
label = "LED6"; label = "LED6";
gpios = <&gpioi 6>; gpios = <&gpioi 6 0>;
default-state = "off"; default-state = "off";
}; };
led7 { led7 {
label = "LED7"; label = "LED7";
gpios = <&gpioi 7>; gpios = <&gpioi 7 0>;
default-state = "off"; default-state = "off";
}; };
led8 { led8 {
label = "LED8"; label = "LED8";
gpios = <&gpioi 8>; gpios = <&gpioi 8 0>;
default-state = "off"; default-state = "off";
}; };
led9 { led9 {
label = "LED9"; label = "LED9";
gpios = <&gpioi 9>; gpios = <&gpioi 9 0>;
default-state = "off"; default-state = "off";
}; };
led10 { led10 {
label = "LED10"; label = "LED10";
gpios = <&gpioi 10>; gpios = <&gpioi 10 0>;
default-state = "off"; default-state = "off";
}; };
led11 { led11 {
label = "LED11"; label = "LED11";
gpios = <&gpioi 11>; gpios = <&gpioi 11 0>;
default-state = "off"; default-state = "off";
}; };
}; };
......
This diff is collapsed.
...@@ -64,62 +64,62 @@ leds { ...@@ -64,62 +64,62 @@ leds {
compatible = "gpio-leds"; compatible = "gpio-leds";
power { power {
label = "Power"; label = "Power";
gpios = <&gpioi 0>; gpios = <&gpioi 0 0>;
linux,default-trigger = "default-on"; linux,default-trigger = "default-on";
}; };
heartbeat { heartbeat {
label = "Heartbeat"; label = "Heartbeat";
gpios = <&gpioi 1>; gpios = <&gpioi 1 0>;
linux,default-trigger = "heartbeat"; linux,default-trigger = "heartbeat";
}; };
led2 { led2 {
label = "LED2"; label = "LED2";
gpios = <&gpioi 2>; gpios = <&gpioi 2 0>;
default-state = "off"; default-state = "off";
}; };
led3 { led3 {
label = "LED3"; label = "LED3";
gpios = <&gpioi 3>; gpios = <&gpioi 3 0>;
default-state = "off"; default-state = "off";
}; };
led4 { led4 {
label = "LED4"; label = "LED4";
gpios = <&gpioi 4>; gpios = <&gpioi 4 0>;
default-state = "off"; default-state = "off";
}; };
led5 { led5 {
label = "LED5"; label = "LED5";
gpios = <&gpioi 5>; gpios = <&gpioi 5 0>;
default-state = "off"; default-state = "off";
}; };
led6 { led6 {
label = "LED6"; label = "LED6";
gpios = <&gpioi 6>; gpios = <&gpioi 6 0>;
default-state = "off"; default-state = "off";
}; };
led7 { led7 {
label = "LED7"; label = "LED7";
gpios = <&gpioi 7>; gpios = <&gpioi 7 0>;
default-state = "off"; default-state = "off";
}; };
led8 { led8 {
label = "LED8"; label = "LED8";
gpios = <&gpioi 8>; gpios = <&gpioi 8 0>;
default-state = "off"; default-state = "off";
}; };
led9 { led9 {
label = "LED9"; label = "LED9";
gpios = <&gpioi 9>; gpios = <&gpioi 9 0>;
default-state = "off"; default-state = "off";
}; };
led10 { led10 {
label = "LED10"; label = "LED10";
gpios = <&gpioi 10>; gpios = <&gpioi 10 0>;
default-state = "off"; default-state = "off";
}; };
led11 { led11 {
label = "LED11"; label = "LED11";
gpios = <&gpioi 11>; gpios = <&gpioi 11 0>;
default-state = "off"; default-state = "off";
}; };
}; };
......
...@@ -62,9 +62,8 @@ ahb_clk: clkdiv_ahb { ...@@ -62,9 +62,8 @@ ahb_clk: clkdiv_ahb {
}; };
iomux: iomux@FF10601c { iomux: iomux@FF10601c {
#address-cells = <1>;
#size-cells = <1>;
compatible = "abilis,tb10x-iomux"; compatible = "abilis,tb10x-iomux";
#gpio-range-cells = <3>;
reg = <0xFF10601c 0x4>; reg = <0xFF10601c 0x4>;
}; };
......
...@@ -67,5 +67,9 @@ phy0: ethernet-phy@0 { ...@@ -67,5 +67,9 @@ phy0: ethernet-phy@0 {
reg = <1>; reg = <1>;
}; };
}; };
arcpmu0: pmu {
compatible = "snps,arc700-pmu";
};
}; };
}; };
CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
# CONFIG_SWAP is not set
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
# CONFIG_SLUB_DEBUG is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_KPROBES=y
CONFIG_MODULES=y
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARC_PLAT_FPGA_LEGACY=y
CONFIG_ARC_BOARD_ML509=y
# CONFIG_ARC_HAS_RTSC is not set
CONFIG_ARC_BUILTIN_DTB_NAME="angel4"
CONFIG_PREEMPT=y
# CONFIG_COMPACTION is not set
# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_UNIX_DIAG=y
CONFIG_NET_KEY=y
CONFIG_INET=y
# CONFIG_IPV6 is not set
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FIRMWARE_IN_KERNEL is not set
# CONFIG_BLK_DEV is not set
CONFIG_NETDEVICES=y
CONFIG_ARC_EMAC=y
CONFIG_LXT_PHY=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_ARC=y
CONFIG_SERIAL_ARC_CONSOLE=y
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
# CONFIG_VGA_CONSOLE is not set
# CONFIG_HID is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_TMPFS=y
# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_NFS_FS=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_XZ_DEC=y
/* /*
* Copyright (C) 2011-2012 Synopsys, Inc. (www.synopsys.com) * Linux performance counter support for ARC
*
* Copyright (C) 2011-2013 Synopsys, Inc. (www.synopsys.com)
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -10,4 +12,204 @@ ...@@ -10,4 +12,204 @@
#ifndef __ASM_PERF_EVENT_H #ifndef __ASM_PERF_EVENT_H
#define __ASM_PERF_EVENT_H #define __ASM_PERF_EVENT_H
/* real maximum varies per CPU, this is the maximum supported by the driver */
#define ARC_PMU_MAX_HWEVENTS 64
#define ARC_REG_CC_BUILD 0xF6
#define ARC_REG_CC_INDEX 0x240
#define ARC_REG_CC_NAME0 0x241
#define ARC_REG_CC_NAME1 0x242
#define ARC_REG_PCT_BUILD 0xF5
#define ARC_REG_PCT_COUNTL 0x250
#define ARC_REG_PCT_COUNTH 0x251
#define ARC_REG_PCT_SNAPL 0x252
#define ARC_REG_PCT_SNAPH 0x253
#define ARC_REG_PCT_CONFIG 0x254
#define ARC_REG_PCT_CONTROL 0x255
#define ARC_REG_PCT_INDEX 0x256
#define ARC_REG_PCT_CONTROL_CC (1 << 16) /* clear counts */
#define ARC_REG_PCT_CONTROL_SN (1 << 17) /* snapshot */
struct arc_reg_pct_build {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int m:8, c:8, r:6, s:2, v:8;
#else
unsigned int v:8, s:2, r:6, c:8, m:8;
#endif
};
struct arc_reg_cc_build {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int c:16, r:8, v:8;
#else
unsigned int v:8, r:8, c:16;
#endif
};
#define PERF_COUNT_ARC_DCLM (PERF_COUNT_HW_MAX + 0)
#define PERF_COUNT_ARC_DCSM (PERF_COUNT_HW_MAX + 1)
#define PERF_COUNT_ARC_ICM (PERF_COUNT_HW_MAX + 2)
#define PERF_COUNT_ARC_BPOK (PERF_COUNT_HW_MAX + 3)
#define PERF_COUNT_ARC_EDTLB (PERF_COUNT_HW_MAX + 4)
#define PERF_COUNT_ARC_EITLB (PERF_COUNT_HW_MAX + 5)
#define PERF_COUNT_ARC_HW_MAX (PERF_COUNT_HW_MAX + 6)
/*
* The "generalized" performance events seem to really be a copy
* of the available events on x86 processors; the mapping to ARC
* events is not always possible 1-to-1. Fortunately, there doesn't
* seem to be an exact definition for these events, so we can cheat
* a bit where necessary.
*
* In particular, the following PERF events may behave a bit differently
* compared to other architectures:
*
* PERF_COUNT_HW_CPU_CYCLES
* Cycles not in halted state
*
* PERF_COUNT_HW_REF_CPU_CYCLES
* Reference cycles not in halted state, same as PERF_COUNT_HW_CPU_CYCLES
* for now as we don't do Dynamic Voltage/Frequency Scaling (yet)
*
* PERF_COUNT_HW_BUS_CYCLES
* Unclear what this means, Intel uses 0x013c, which according to
* their datasheet means "unhalted reference cycles". It sounds similar
* to PERF_COUNT_HW_REF_CPU_CYCLES, and we use the same counter for it.
*
* PERF_COUNT_HW_STALLED_CYCLES_BACKEND
* PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
* The ARC 700 can either measure stalls per pipeline stage, or all stalls
* combined; for now we assign all stalls to STALLED_CYCLES_BACKEND
* and all pipeline flushes (e.g. caused by mispredicts, etc.) to
* STALLED_CYCLES_FRONTEND.
*
* We could start multiple performance counters and combine everything
* afterwards, but that makes it complicated.
*
* Note that I$ cache misses aren't counted by either of the two!
*/
static const char * const arc_pmu_ev_hw_map[] = {
[PERF_COUNT_HW_CPU_CYCLES] = "crun",
[PERF_COUNT_HW_REF_CPU_CYCLES] = "crun",
[PERF_COUNT_HW_BUS_CYCLES] = "crun",
[PERF_COUNT_HW_INSTRUCTIONS] = "iall",
[PERF_COUNT_HW_BRANCH_MISSES] = "bpfail",
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "ijmp",
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = "bflush",
[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = "bstall",
[PERF_COUNT_ARC_DCLM] = "dclm",
[PERF_COUNT_ARC_DCSM] = "dcsm",
[PERF_COUNT_ARC_ICM] = "icm",
[PERF_COUNT_ARC_BPOK] = "bpok",
[PERF_COUNT_ARC_EDTLB] = "edtlb",
[PERF_COUNT_ARC_EITLB] = "eitlb",
};
#define C(_x) PERF_COUNT_HW_CACHE_##_x
#define CACHE_OP_UNSUPPORTED 0xffff
static const unsigned arc_pmu_cache_map[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
[C(L1D)] = {
[C(OP_READ)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = PERF_COUNT_ARC_DCLM,
},
[C(OP_WRITE)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = PERF_COUNT_ARC_DCSM,
},
[C(OP_PREFETCH)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
},
[C(L1I)] = {
[C(OP_READ)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = PERF_COUNT_ARC_ICM,
},
[C(OP_WRITE)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
[C(OP_PREFETCH)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
},
[C(LL)] = {
[C(OP_READ)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
[C(OP_WRITE)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
[C(OP_PREFETCH)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
},
[C(DTLB)] = {
[C(OP_READ)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = PERF_COUNT_ARC_EDTLB,
},
[C(OP_WRITE)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
[C(OP_PREFETCH)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
},
[C(ITLB)] = {
[C(OP_READ)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = PERF_COUNT_ARC_EITLB,
},
[C(OP_WRITE)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
[C(OP_PREFETCH)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
},
[C(BPU)] = {
[C(OP_READ)] = {
[C(RESULT_ACCESS)] = PERF_COUNT_HW_BRANCH_INSTRUCTIONS,
[C(RESULT_MISS)] = PERF_COUNT_HW_BRANCH_MISSES,
},
[C(OP_WRITE)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
[C(OP_PREFETCH)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
},
[C(NODE)] = {
[C(OP_READ)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
[C(OP_WRITE)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
[C(OP_PREFETCH)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
},
};
#endif /* __ASM_PERF_EVENT_H */ #endif /* __ASM_PERF_EVENT_H */
...@@ -19,6 +19,7 @@ obj-$(CONFIG_KPROBES) += kprobes.o ...@@ -19,6 +19,7 @@ obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_ARC_MISALIGN_ACCESS) += unaligned.o obj-$(CONFIG_ARC_MISALIGN_ACCESS) += unaligned.o
obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_ARC_METAWARE_HLINK) += arc_hostlink.o obj-$(CONFIG_ARC_METAWARE_HLINK) += arc_hostlink.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o
obj-$(CONFIG_ARC_FPU_SAVE_RESTORE) += fpu.o obj-$(CONFIG_ARC_FPU_SAVE_RESTORE) += fpu.o
CFLAGS_fpu.o += -mdpfp CFLAGS_fpu.o += -mdpfp
......
/*
* Linux performance counter support for ARC700 series
*
* Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com)
*
* This code is inspired by the perf support of various other architectures.
*
* 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/errno.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/perf_event.h>
#include <linux/platform_device.h>
#include <asm/arcregs.h>
struct arc_pmu {
struct pmu pmu;
int counter_size; /* in bits */
int n_counters;
unsigned long used_mask[BITS_TO_LONGS(ARC_PMU_MAX_HWEVENTS)];
int ev_hw_idx[PERF_COUNT_ARC_HW_MAX];
};
/* read counter #idx; note that counter# != event# on ARC! */
static uint64_t arc_pmu_read_counter(int idx)
{
uint32_t tmp;
uint64_t result;
/*
* ARC supports making 'snapshots' of the counters, so we don't
* need to care about counters wrapping to 0 underneath our feet
*/
write_aux_reg(ARC_REG_PCT_INDEX, idx);
tmp = read_aux_reg(ARC_REG_PCT_CONTROL);
write_aux_reg(ARC_REG_PCT_CONTROL, tmp | ARC_REG_PCT_CONTROL_SN);
result = (uint64_t) (read_aux_reg(ARC_REG_PCT_SNAPH)) << 32;
result |= read_aux_reg(ARC_REG_PCT_SNAPL);
return result;
}
static void arc_perf_event_update(struct perf_event *event,
struct hw_perf_event *hwc, int idx)
{
struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu);
uint64_t prev_raw_count, new_raw_count;
int64_t delta;
do {
prev_raw_count = local64_read(&hwc->prev_count);
new_raw_count = arc_pmu_read_counter(idx);
} while (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
new_raw_count) != prev_raw_count);
delta = (new_raw_count - prev_raw_count) &
((1ULL << arc_pmu->counter_size) - 1ULL);
local64_add(delta, &event->count);
local64_sub(delta, &hwc->period_left);
}
static void arc_pmu_read(struct perf_event *event)
{
arc_perf_event_update(event, &event->hw, event->hw.idx);
}
static int arc_pmu_cache_event(u64 config)
{
unsigned int cache_type, cache_op, cache_result;
int ret;
cache_type = (config >> 0) & 0xff;
cache_op = (config >> 8) & 0xff;
cache_result = (config >> 16) & 0xff;
if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
return -EINVAL;
if (cache_type >= PERF_COUNT_HW_CACHE_OP_MAX)
return -EINVAL;
if (cache_type >= PERF_COUNT_HW_CACHE_RESULT_MAX)
return -EINVAL;
ret = arc_pmu_cache_map[cache_type][cache_op][cache_result];
if (ret == CACHE_OP_UNSUPPORTED)
return -ENOENT;
return ret;
}
/* initializes hw_perf_event structure if event is supported */
static int arc_pmu_event_init(struct perf_event *event)
{
struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu);
struct hw_perf_event *hwc = &event->hw;
int ret;
/* ARC 700 PMU does not support sampling events */
if (is_sampling_event(event))
return -ENOENT;
switch (event->attr.type) {
case PERF_TYPE_HARDWARE:
if (event->attr.config >= PERF_COUNT_HW_MAX)
return -ENOENT;
if (arc_pmu->ev_hw_idx[event->attr.config] < 0)
return -ENOENT;
hwc->config = arc_pmu->ev_hw_idx[event->attr.config];
pr_debug("initializing event %d with cfg %d\n",
(int) event->attr.config, (int) hwc->config);
return 0;
case PERF_TYPE_HW_CACHE:
ret = arc_pmu_cache_event(event->attr.config);
if (ret < 0)
return ret;
hwc->config = arc_pmu->ev_hw_idx[ret];
return 0;
default:
return -ENOENT;
}
}
/* starts all counters */
static void arc_pmu_enable(struct pmu *pmu)
{
uint32_t tmp;
tmp = read_aux_reg(ARC_REG_PCT_CONTROL);
write_aux_reg(ARC_REG_PCT_CONTROL, (tmp & 0xffff0000) | 0x1);
}
/* stops all counters */
static void arc_pmu_disable(struct pmu *pmu)
{
uint32_t tmp;
tmp = read_aux_reg(ARC_REG_PCT_CONTROL);
write_aux_reg(ARC_REG_PCT_CONTROL, (tmp & 0xffff0000) | 0x0);
}
/*
* Assigns hardware counter to hardware condition.
* Note that there is no separate start/stop mechanism;
* stopping is achieved by assigning the 'never' condition
*/
static void arc_pmu_start(struct perf_event *event, int flags)
{
struct hw_perf_event *hwc = &event->hw;
int idx = hwc->idx;
if (WARN_ON_ONCE(idx == -1))
return;
if (flags & PERF_EF_RELOAD)
WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
event->hw.state = 0;
/* enable ARC pmu here */
write_aux_reg(ARC_REG_PCT_INDEX, idx);
write_aux_reg(ARC_REG_PCT_CONFIG, hwc->config);
}
static void arc_pmu_stop(struct perf_event *event, int flags)
{
struct hw_perf_event *hwc = &event->hw;
int idx = hwc->idx;
if (!(event->hw.state & PERF_HES_STOPPED)) {
/* stop ARC pmu here */
write_aux_reg(ARC_REG_PCT_INDEX, idx);
/* condition code #0 is always "never" */
write_aux_reg(ARC_REG_PCT_CONFIG, 0);
event->hw.state |= PERF_HES_STOPPED;
}
if ((flags & PERF_EF_UPDATE) &&
!(event->hw.state & PERF_HES_UPTODATE)) {
arc_perf_event_update(event, &event->hw, idx);
event->hw.state |= PERF_HES_UPTODATE;
}
}
static void arc_pmu_del(struct perf_event *event, int flags)
{
struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu);
arc_pmu_stop(event, PERF_EF_UPDATE);
__clear_bit(event->hw.idx, arc_pmu->used_mask);
perf_event_update_userpage(event);
}
/* allocate hardware counter and optionally start counting */
static int arc_pmu_add(struct perf_event *event, int flags)
{
struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu);
struct hw_perf_event *hwc = &event->hw;
int idx = hwc->idx;
if (__test_and_set_bit(idx, arc_pmu->used_mask)) {
idx = find_first_zero_bit(arc_pmu->used_mask,
arc_pmu->n_counters);
if (idx == arc_pmu->n_counters)
return -EAGAIN;
__set_bit(idx, arc_pmu->used_mask);
hwc->idx = idx;
}
write_aux_reg(ARC_REG_PCT_INDEX, idx);
write_aux_reg(ARC_REG_PCT_CONFIG, 0);
write_aux_reg(ARC_REG_PCT_COUNTL, 0);
write_aux_reg(ARC_REG_PCT_COUNTH, 0);
local64_set(&hwc->prev_count, 0);
hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
if (flags & PERF_EF_START)
arc_pmu_start(event, PERF_EF_RELOAD);
perf_event_update_userpage(event);
return 0;
}
static int arc_pmu_device_probe(struct platform_device *pdev)
{
struct arc_pmu *arc_pmu;
struct arc_reg_pct_build pct_bcr;
struct arc_reg_cc_build cc_bcr;
int i, j, ret;
union cc_name {
struct {
uint32_t word0, word1;
char sentinel;
} indiv;
char str[9];
} cc_name;
READ_BCR(ARC_REG_PCT_BUILD, pct_bcr);
if (!pct_bcr.v) {
pr_err("This core does not have performance counters!\n");
return -ENODEV;
}
arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu),
GFP_KERNEL);
if (!arc_pmu)
return -ENOMEM;
arc_pmu->n_counters = pct_bcr.c;
BUG_ON(arc_pmu->n_counters > ARC_PMU_MAX_HWEVENTS);
arc_pmu->counter_size = 32 + (pct_bcr.s << 4);
pr_info("ARC PMU found with %d counters of size %d bits\n",
arc_pmu->n_counters, arc_pmu->counter_size);
READ_BCR(ARC_REG_CC_BUILD, cc_bcr);
if (!cc_bcr.v)
pr_err("Strange! Performance counters exist, but no countable conditions?\n");
pr_info("ARC PMU has %d countable conditions\n", cc_bcr.c);
cc_name.str[8] = 0;
for (i = 0; i < PERF_COUNT_HW_MAX; i++)
arc_pmu->ev_hw_idx[i] = -1;
for (j = 0; j < cc_bcr.c; j++) {
write_aux_reg(ARC_REG_CC_INDEX, j);
cc_name.indiv.word0 = read_aux_reg(ARC_REG_CC_NAME0);
cc_name.indiv.word1 = read_aux_reg(ARC_REG_CC_NAME1);
for (i = 0; i < ARRAY_SIZE(arc_pmu_ev_hw_map); i++) {
if (arc_pmu_ev_hw_map[i] &&
!strcmp(arc_pmu_ev_hw_map[i], cc_name.str) &&
strlen(arc_pmu_ev_hw_map[i])) {
pr_debug("mapping %d to idx %d with name %s\n",
i, j, cc_name.str);
arc_pmu->ev_hw_idx[i] = j;
}
}
}
arc_pmu->pmu = (struct pmu) {
.pmu_enable = arc_pmu_enable,
.pmu_disable = arc_pmu_disable,
.event_init = arc_pmu_event_init,
.add = arc_pmu_add,
.del = arc_pmu_del,
.start = arc_pmu_start,
.stop = arc_pmu_stop,
.read = arc_pmu_read,
};
ret = perf_pmu_register(&arc_pmu->pmu, pdev->name, PERF_TYPE_RAW);
return ret;
}
#ifdef CONFIG_OF
static const struct of_device_id arc_pmu_match[] = {
{ .compatible = "snps,arc700-pmu" },
{},
};
MODULE_DEVICE_TABLE(of, arc_pmu_match);
#endif
static struct platform_driver arc_pmu_driver = {
.driver = {
.name = "arc700-pmu",
.of_match_table = of_match_ptr(arc_pmu_match),
},
.probe = arc_pmu_device_probe,
};
module_platform_driver(arc_pmu_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mischa Jonker <mjonker@synopsys.com>");
MODULE_DESCRIPTION("ARC PMU driver");
...@@ -20,8 +20,10 @@ menuconfig ARC_PLAT_TB10X ...@@ -20,8 +20,10 @@ menuconfig ARC_PLAT_TB10X
bool "Abilis TB10x" bool "Abilis TB10x"
select COMMON_CLK select COMMON_CLK
select PINCTRL select PINCTRL
select PINCTRL_TB10X
select PINMUX select PINMUX
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select GPIO_TB10X
select TB10X_IRQC select TB10X_IRQC
help help
Support for platforms based on the TB10x home media gateway SOC by Support for platforms based on the TB10x home media gateway SOC by
......
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