diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-mx3/mach-mx31moboard.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-orion5x/dns323-setup.c | 22 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/mach-gta02.c | 76 | ||||
-rw-r--r-- | arch/sparc/kernel/perf_event.c | 108 | ||||
-rw-r--r-- | arch/x86/include/asm/perf_event_p4.h | 3 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_p4.c | 41 | ||||
-rw-r--r-- | arch/x86/mm/pf_in.c | 2 |
8 files changed, 155 insertions, 148 deletions
diff --git a/arch/arm/mach-mx3/mach-mx31moboard.c b/arch/arm/mach-mx3/mach-mx31moboard.c index 33a8d35498a7..62b5e40165df 100644 --- a/arch/arm/mach-mx3/mach-mx31moboard.c +++ b/arch/arm/mach-mx3/mach-mx31moboard.c @@ -220,11 +220,54 @@ static struct mc13783_regulator_init_data moboard_regulators[] = { }, }; +static struct mc13783_led_platform_data moboard_led[] = { + { + .id = MC13783_LED_R1, + .name = "coreboard-led-4:red", + .max_current = 2, + }, + { + .id = MC13783_LED_G1, + .name = "coreboard-led-4:green", + .max_current = 2, + }, + { + .id = MC13783_LED_B1, + .name = "coreboard-led-4:blue", + .max_current = 2, + }, + { + .id = MC13783_LED_R2, + .name = "coreboard-led-5:red", + .max_current = 3, + }, + { + .id = MC13783_LED_G2, + .name = "coreboard-led-5:green", + .max_current = 3, + }, + { + .id = MC13783_LED_B2, + .name = "coreboard-led-5:blue", + .max_current = 3, + }, +}; + +static struct mc13783_leds_platform_data moboard_leds = { + .num_leds = ARRAY_SIZE(moboard_led), + .led = moboard_led, + .flags = MC13783_LED_SLEWLIMTC, + .abmode = MC13783_LED_AB_DISABLED, + .tc1_period = MC13783_LED_PERIOD_10MS, + .tc2_period = MC13783_LED_PERIOD_10MS, +}; + static struct mc13783_platform_data moboard_pmic = { .regulators = moboard_regulators, .num_regulators = ARRAY_SIZE(moboard_regulators), + .leds = &moboard_leds, .flags = MC13783_USE_REGULATOR | MC13783_USE_RTC | - MC13783_USE_ADC, + MC13783_USE_ADC | MC13783_USE_LED, }; static struct spi_board_info moboard_spi_board_info[] __initdata = { diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c index 685f34a9634b..fe0de1698edc 100644 --- a/arch/arm/mach-orion5x/dns323-setup.c +++ b/arch/arm/mach-orion5x/dns323-setup.c @@ -240,22 +240,23 @@ error_fail: #define ORION_BLINK_HALF_PERIOD 100 /* ms */ -static int dns323_gpio_blink_set(unsigned gpio, +static int dns323_gpio_blink_set(unsigned gpio, int state, unsigned long *delay_on, unsigned long *delay_off) { - static int value = 0; - if (!*delay_on && !*delay_off) + if (delay_on && delay_off && !*delay_on && !*delay_off) *delay_on = *delay_off = ORION_BLINK_HALF_PERIOD; - if (ORION_BLINK_HALF_PERIOD == *delay_on - && ORION_BLINK_HALF_PERIOD == *delay_off) { - value = !value; - orion_gpio_set_blink(gpio, value); - return 0; + switch(state) { + case GPIO_LED_NO_BLINK_LOW: + case GPIO_LED_NO_BLINK_HIGH: + orion_gpio_set_blink(gpio, 0); + gpio_set_value(gpio, state); + break; + case GPIO_LED_BLINK: + orion_gpio_set_blink(gpio, 1); } - - return -EINVAL; + return 0; } static struct gpio_led dns323_leds[] = { @@ -263,6 +264,7 @@ static struct gpio_led dns323_leds[] = { .name = "power:blue", .gpio = DNS323_GPIO_LED_POWER2, .default_trigger = "timer", + .active_low = 1, }, { .name = "right:amber", .gpio = DNS323_GPIO_LED_RIGHT_AMBER, diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c index 45799c608d8f..9e39faa283b9 100644 --- a/arch/arm/mach-s3c2440/mach-gta02.c +++ b/arch/arm/mach-s3c2440/mach-gta02.c @@ -49,7 +49,6 @@ #include <linux/io.h> #include <linux/i2c.h> -#include <linux/backlight.h> #include <linux/regulator/machine.h> #include <linux/mfd/pcf50633/core.h> @@ -57,6 +56,7 @@ #include <linux/mfd/pcf50633/adc.h> #include <linux/mfd/pcf50633/gpio.h> #include <linux/mfd/pcf50633/pmic.h> +#include <linux/mfd/pcf50633/backlight.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -254,6 +254,12 @@ static char *gta02_batteries[] = { "battery", }; +static struct pcf50633_bl_platform_data gta02_backlight_data = { + .default_brightness = 0x3f, + .default_brightness_limit = 0, + .ramp_time = 5, +}; + struct pcf50633_platform_data gta02_pcf_pdata = { .resumers = { [0] = PCF50633_INT1_USBINS | @@ -271,6 +277,8 @@ struct pcf50633_platform_data gta02_pcf_pdata = { .charger_reference_current_ma = 1000, + .backlight_data = >a02_backlight_data, + .reg_init_data = { [PCF50633_REGULATOR_AUTO] = { .constraints = { @@ -478,71 +486,6 @@ static struct s3c2410_udc_mach_info gta02_udc_cfg = { }; - - -static void gta02_bl_set_intensity(int intensity) -{ - struct pcf50633 *pcf = gta02_pcf; - int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT); - - /* We map 8-bit intensity to 6-bit intensity in hardware. */ - intensity >>= 2; - - /* - * This can happen during, eg, print of panic on blanked console, - * but we can't service i2c without interrupts active, so abort. - */ - if (in_atomic()) { - printk(KERN_ERR "gta02_bl_set_intensity called while atomic\n"); - return; - } - - old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT); - if (intensity == old_intensity) - return; - - /* We can't do this anywhere else. */ - pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 5); - - if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 3)) - old_intensity = 0; - - /* - * The PCF50633 cannot handle LEDOUT = 0 (datasheet p60) - * if seen, you have to re-enable the LED unit. - */ - if (!intensity || !old_intensity) - pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0); - - /* Illegal to set LEDOUT to 0. */ - if (!intensity) - pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, 2); - else - pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, - intensity); - - if (intensity) - pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 2); - -} - -static struct generic_bl_info gta02_bl_info = { - .name = "gta02-bl", - .max_intensity = 0xff, - .default_intensity = 0xff, - .set_bl_intensity = gta02_bl_set_intensity, -}; - -static struct platform_device gta02_bl_dev = { - .name = "generic-bl", - .id = 1, - .dev = { - .platform_data = >a02_bl_info, - }, -}; - - - /* USB */ static struct s3c2410_hcd_info gta02_usb_info __initdata = { .port[0] = { @@ -579,7 +522,6 @@ static struct platform_device *gta02_devices[] __initdata = { /* These guys DO need to be children of PMU. */ static struct platform_device *gta02_devices_pmu_children[] = { - >a02_bl_dev, }; diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 34ce49f80eac..0ec92c8861dd 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -92,6 +92,8 @@ struct cpu_hw_events { /* Enabled/disable state. */ int enabled; + + unsigned int group_flag; }; DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, }; @@ -981,53 +983,6 @@ static int collect_events(struct perf_event *group, int max_count, return n; } -static void event_sched_in(struct perf_event *event) -{ - event->state = PERF_EVENT_STATE_ACTIVE; - event->oncpu = smp_processor_id(); - event->tstamp_running += event->ctx->time - event->tstamp_stopped; - if (is_software_event(event)) - event->pmu->enable(event); -} - -int hw_perf_group_sched_in(struct perf_event *group_leader, - struct perf_cpu_context *cpuctx, - struct perf_event_context *ctx) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - struct perf_event *sub; - int n0, n; - - if (!sparc_pmu) - return 0; - - n0 = cpuc->n_events; - n = collect_events(group_leader, perf_max_events - n0, - &cpuc->event[n0], &cpuc->events[n0], - &cpuc->current_idx[n0]); - if (n < 0) - return -EAGAIN; - if (check_excludes(cpuc->event, n0, n)) - return -EINVAL; - if (sparc_check_constraints(cpuc->event, cpuc->events, n + n0)) - return -EAGAIN; - cpuc->n_events = n0 + n; - cpuc->n_added += n; - - cpuctx->active_oncpu += n; - n = 1; - event_sched_in(group_leader); - list_for_each_entry(sub, &group_leader->sibling_list, group_entry) { - if (sub->state != PERF_EVENT_STATE_OFF) { - event_sched_in(sub); - n++; - } - } - ctx->nr_active += n; - - return 1; -} - static int sparc_pmu_enable(struct perf_event *event) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); @@ -1045,11 +1000,20 @@ static int sparc_pmu_enable(struct perf_event *event) cpuc->events[n0] = event->hw.event_base; cpuc->current_idx[n0] = PIC_NO_INDEX; + /* + * If group events scheduling transaction was started, + * skip the schedulability test here, it will be peformed + * at commit time(->commit_txn) as a whole + */ + if (cpuc->group_flag & PERF_EVENT_TXN_STARTED) + goto nocheck; + if (check_excludes(cpuc->event, n0, 1)) goto out; if (sparc_check_constraints(cpuc->event, cpuc->events, n0 + 1)) goto out; +nocheck: cpuc->n_events++; cpuc->n_added++; @@ -1129,11 +1093,61 @@ static int __hw_perf_event_init(struct perf_event *event) return 0; } +/* + * Start group events scheduling transaction + * Set the flag to make pmu::enable() not perform the + * schedulability test, it will be performed at commit time + */ +static void sparc_pmu_start_txn(const struct pmu *pmu) +{ + struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); + + cpuhw->group_flag |= PERF_EVENT_TXN_STARTED; +} + +/* + * Stop group events scheduling transaction + * Clear the flag and pmu::enable() will perform the + * schedulability test. + */ +static void sparc_pmu_cancel_txn(const struct pmu *pmu) +{ + struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); + + cpuhw->group_flag &= ~PERF_EVENT_TXN_STARTED; +} + +/* + * Commit group events scheduling transaction + * Perform the group schedulability test as a whole + * Return 0 if success + */ +static int sparc_pmu_commit_txn(const struct pmu *pmu) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + int n; + + if (!sparc_pmu) + return -EINVAL; + + cpuc = &__get_cpu_var(cpu_hw_events); + n = cpuc->n_events; + if (check_excludes(cpuc->event, 0, n)) + return -EINVAL; + if (sparc_check_constraints(cpuc->event, cpuc->events, n)) + return -EAGAIN; + + return 0; +} + static const struct pmu pmu = { .enable = sparc_pmu_enable, .disable = sparc_pmu_disable, .read = sparc_pmu_read, .unthrottle = sparc_pmu_unthrottle, + .start_txn = sparc_pmu_start_txn, + .cancel_txn = sparc_pmu_cancel_txn, + .commit_txn = sparc_pmu_commit_txn, }; const struct pmu *hw_perf_event_init(struct perf_event *event) diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h index b05400a542ff..64a8ebff06fc 100644 --- a/arch/x86/include/asm/perf_event_p4.h +++ b/arch/x86/include/asm/perf_event_p4.h @@ -89,7 +89,8 @@ P4_CCCR_ENABLE) /* HT mask */ -#define P4_CCCR_MASK_HT (P4_CCCR_MASK | P4_CCCR_THREAD_ANY) +#define P4_CCCR_MASK_HT \ + (P4_CCCR_MASK | P4_CCCR_OVF_PMI_T1 | P4_CCCR_THREAD_ANY) #define P4_GEN_ESCR_EMASK(class, name, bit) \ class##__##name = ((1 << bit) << P4_ESCR_EVENTMASK_SHIFT) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index fd4db0db3708..c77586061bcb 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1717,7 +1717,11 @@ void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int ski */ regs->bp = rewind_frame_pointer(skip + 1); regs->cs = __KERNEL_CS; - local_save_flags(regs->flags); + /* + * We abuse bit 3 to pass exact information, see perf_misc_flags + * and the comment with PERF_EFLAGS_EXACT. + */ + regs->flags = 0; } unsigned long perf_instruction_pointer(struct pt_regs *regs) diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 424fc8de68e4..ae85d69644d1 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -465,15 +465,21 @@ out: return rc; } -static inline void p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc) +static inline int p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc) { - unsigned long dummy; + int overflow = 0; + u32 low, high; - rdmsrl(hwc->config_base + hwc->idx, dummy); - if (dummy & P4_CCCR_OVF) { + rdmsr(hwc->config_base + hwc->idx, low, high); + + /* we need to check high bit for unflagged overflows */ + if ((low & P4_CCCR_OVF) || !(high & (1 << 31))) { + overflow = 1; (void)checking_wrmsrl(hwc->config_base + hwc->idx, - ((u64)dummy) & ~P4_CCCR_OVF); + ((u64)low) & ~P4_CCCR_OVF); } + + return overflow; } static inline void p4_pmu_disable_event(struct perf_event *event) @@ -584,21 +590,15 @@ static int p4_pmu_handle_irq(struct pt_regs *regs) WARN_ON_ONCE(hwc->idx != idx); - /* - * FIXME: Redundant call, actually not needed - * but just to check if we're screwed - */ - p4_pmu_clear_cccr_ovf(hwc); + /* it might be unflagged overflow */ + handled = p4_pmu_clear_cccr_ovf(hwc); val = x86_perf_event_update(event); - if (val & (1ULL << (x86_pmu.cntval_bits - 1))) + if (!handled && (val & (1ULL << (x86_pmu.cntval_bits - 1)))) continue; - /* - * event overflow - */ - handled = 1; - data.period = event->hw.last_period; + /* event overflow for sure */ + data.period = event->hw.last_period; if (!x86_perf_event_set_period(event)) continue; @@ -670,7 +670,7 @@ static void p4_pmu_swap_config_ts(struct hw_perf_event *hwc, int cpu) /* * ESCR address hashing is tricky, ESCRs are not sequential - * in memory but all starts from MSR_P4_BSU_ESCR0 (0x03e0) and + * in memory but all starts from MSR_P4_BSU_ESCR0 (0x03a0) and * the metric between any ESCRs is laid in range [0xa0,0xe1] * * so we make ~70% filled hashtable @@ -735,8 +735,9 @@ static int p4_get_escr_idx(unsigned int addr) { unsigned int idx = P4_ESCR_MSR_IDX(addr); - if (unlikely(idx >= P4_ESCR_MSR_TABLE_SIZE || - !p4_escr_table[idx])) { + if (unlikely(idx >= P4_ESCR_MSR_TABLE_SIZE || + !p4_escr_table[idx] || + p4_escr_table[idx] != addr)) { WARN_ONCE(1, "P4 PMU: Wrong address passed: %x\n", addr); return -1; } @@ -762,7 +763,7 @@ static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign { unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; unsigned long escr_mask[BITS_TO_LONGS(P4_ESCR_MSR_TABLE_SIZE)]; - int cpu = raw_smp_processor_id(); + int cpu = smp_processor_id(); struct hw_perf_event *hwc; struct p4_event_bind *bind; unsigned int i, thread, num; diff --git a/arch/x86/mm/pf_in.c b/arch/x86/mm/pf_in.c index df3d5c861cda..308e32570d84 100644 --- a/arch/x86/mm/pf_in.c +++ b/arch/x86/mm/pf_in.c @@ -34,7 +34,7 @@ /* IA32 Manual 3, 2-1 */ static unsigned char prefix_codes[] = { 0xF0, 0xF2, 0xF3, 0x2E, 0x36, 0x3E, 0x26, 0x64, - 0x65, 0x2E, 0x3E, 0x66, 0x67 + 0x65, 0x66, 0x67 }; /* IA32 Manual 3, 3-432*/ static unsigned int reg_rop[] = { |