// SPDX-License-Identifier: GPL-2.0
/*
* Generic SH - 4 / SH - 4 A PCIC operations ( SH7751 , SH7780 ) .
*
* Copyright ( C ) 2002 - 2009 Paul Mundt
*/
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <asm /addrspace.h>
#include "pci-sh4.h"
/*
* Direct access to PCI hardware . . .
*/
#define CONFIG_CMD(bus, devfn, where) \
(0 x80000000 | (bus->number << 16 ) | (devfn << 8 ) | (where & ~3 ))
/*
* Functions for accessing PCI configuration space with type 1 accesses
*/
static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
struct pci_channel *chan = bus->sysdata;
unsigned long flags;
u32 data;
/*
* PCIPDR may only be accessed as 32 bit words ,
* so we must do byte alignment by hand
*/
raw_spin_lock_irqsave(&pci_config_lock, flags);
pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
data = pci_read_reg(chan, SH4_PCIPDR);
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
switch (size) {
case 1 :
*val = (data >> ((where & 3 ) << 3 )) & 0 xff;
break ;
case 2 :
*val = (data >> ((where & 2 ) << 3 )) & 0 xffff;
break ;
case 4 :
*val = data;
break ;
default :
return PCIBIOS_FUNC_NOT_SUPPORTED;
}
return PCIBIOS_SUCCESSFUL;
}
/*
* Since SH4 only does 32 bit access we ' ll have to do a read ,
* mask , write operation .
* We ' ll allow an odd byte offset , though it should be illegal .
*/
static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 val)
{
struct pci_channel *chan = bus->sysdata;
unsigned long flags;
int shift;
u32 data;
raw_spin_lock_irqsave(&pci_config_lock, flags);
pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
data = pci_read_reg(chan, SH4_PCIPDR);
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
switch (size) {
case 1 :
shift = (where & 3 ) << 3 ;
data &= ~(0 xff << shift);
data |= ((val & 0 xff) << shift);
break ;
case 2 :
shift = (where & 2 ) << 3 ;
data &= ~(0 xffff << shift);
data |= ((val & 0 xffff) << shift);
break ;
case 4 :
data = val;
break ;
default :
return PCIBIOS_FUNC_NOT_SUPPORTED;
}
pci_write_reg(chan, data, SH4_PCIPDR);
return PCIBIOS_SUCCESSFUL;
}
struct pci_ops sh4_pci_ops = {
.read = sh4_pci_read,
.write = sh4_pci_write,
};
int __attribute__((weak)) pci_fixup_pcic(struct pci_channel *chan)
{
/* Nothing to do. */
return 0 ;
}
Messung V0.5 in Prozent C=98 H=100 G=98
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland